Extract ClassResolver class from JavaDescriptorResolver

This commit is contained in:
Pavel V. Talanov
2012-10-06 18:45:00 +04:00
parent bcb6686805
commit 2d33b50b55
4 changed files with 257 additions and 150 deletions
@@ -146,7 +146,7 @@ public class JavaDescriptorResolveData {
super(negative);
}
static final ResolverClassData NEGATIVE = new ResolverBinaryClassData(true);
public static final ResolverClassData NEGATIVE = new ResolverBinaryClassData(true);
}
public static class ResolverClassData extends ResolverScopeData {
@@ -32,13 +32,16 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.constants.*;
import org.jetbrains.jet.lang.resolve.constants.StringValue;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.*;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverClassData;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverNamespaceData;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverScopeData;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverSyntheticClassObjectClassData;
import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode;
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaNamespaceDescriptor;
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeMethodSignatureData;
import org.jetbrains.jet.lang.resolve.java.kt.DescriptorKindUtils;
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation;
import org.jetbrains.jet.lang.resolve.java.kt.PsiAnnotationWithFlags;
import org.jetbrains.jet.lang.resolve.java.resolver.ClassResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaDescriptorPropertiesResolver;
import org.jetbrains.jet.lang.resolve.java.scope.JavaClassMembersScope;
import org.jetbrains.jet.lang.resolve.java.scope.JavaPackageScope;
@@ -121,6 +124,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
private PsiClassFinder psiClassFinder;
private JavaDescriptorSignatureResolver javaDescriptorSignatureResolver;
private JavaDescriptorPropertiesResolver javaDescriptorPropertiesResolver = new JavaDescriptorPropertiesResolver(this);
private final ClassResolver classResolver = new ClassResolver(this);
@Inject
public void setProject(Project project) {
@@ -153,7 +157,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
@Nullable
private ClassDescriptor resolveJavaLangObject() {
ClassDescriptor clazz = resolveClass(OBJECT_FQ_NAME, DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN);
ClassDescriptor clazz = classResolver.resolveClass(OBJECT_FQ_NAME, DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN);
if (clazz == null) {
// TODO: warning
}
@@ -162,148 +166,32 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
@Nullable
public ClassDescriptor resolveClass(@NotNull FqName qualifiedName, @NotNull DescriptorSearchRule searchRule) {
List<Runnable> tasks = Lists.newArrayList();
ClassDescriptor clazz = resolveClass(qualifiedName, searchRule, tasks);
for (Runnable task : tasks) {
task.run();
}
return clazz;
return classResolver.resolveClass(qualifiedName, searchRule);
}
@Override
public ClassDescriptor resolveClass(@NotNull FqName qualifiedName) {
return resolveClass(qualifiedName, DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
return classResolver.resolveClass(qualifiedName);
}
private ClassDescriptor resolveClass(@NotNull FqName qualifiedName, @NotNull DescriptorSearchRule searchRule, @NotNull List<Runnable> tasks) {
if (qualifiedName.getFqName().endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) {
// TODO: only if -$$TImpl class is created by Kotlin
return null;
}
ClassDescriptor builtinClassDescriptor = semanticServices.getKotlinBuiltinClassDescriptor(qualifiedName);
if (builtinClassDescriptor != null) {
return builtinClassDescriptor;
}
// First, let's check that this is a real Java class, not a Java's view on a Kotlin class:
ClassDescriptor kotlinClassDescriptor = semanticServices.getKotlinClassDescriptor(qualifiedName);
if (kotlinClassDescriptor != null) {
if (searchRule == DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN) {
throw new IllegalStateException("class must not be found in kotlin: " + qualifiedName);
}
else if (searchRule == DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN) {
return null;
}
else if (searchRule == DescriptorSearchRule.INCLUDE_KOTLIN) {
return kotlinClassDescriptor;
}
else {
throw new IllegalStateException("unknown searchRule: " + searchRule);
}
}
// Not let's take a descriptor of a Java class
ResolverClassData classData = classDescriptorCache.get(qualifiedName);
if (classData == null) {
PsiClass psiClass = psiClassFinder.findPsiClass(qualifiedName, PsiClassFinder.RuntimeClassesHandleMode.THROW);
if (psiClass == null) {
ResolverClassData oldValue = classDescriptorCache.put(qualifiedName, ResolverBinaryClassData.NEGATIVE);
if (oldValue != null) {
throw new IllegalStateException("rewrite at " + qualifiedName);
}
return null;
}
classData = createJavaClassDescriptor(psiClass, tasks);
}
return classData.getClassDescriptor();
public PsiClassFinder getPsiClassFinder() {
return psiClassFinder;
}
@NotNull
private ResolverClassData createJavaClassDescriptor(@NotNull final PsiClass psiClass, List<Runnable> taskList) {
final String qualifiedName = psiClass.getQualifiedName();
assert qualifiedName != null;
FqName fqName = new FqName(qualifiedName);
if (classDescriptorCache.containsKey(fqName)) {
throw new IllegalStateException(qualifiedName);
}
checkPsiClassIsNotJet(psiClass);
Name name = Name.identifier(psiClass.getName());
JetClassAnnotation jetClassAnnotation = JetClassAnnotation.get(psiClass);
ClassKind kind = getClassKind(psiClass, jetClassAnnotation);
ClassOrNamespaceDescriptor containingDeclaration = resolveParentDescriptor(psiClass);
// class may be resolved during resolution of parent
ResolverClassData classData = classDescriptorCache.get(fqName);
if (classData != null) {
return classData;
}
classData = new ClassDescriptorFromJvmBytecode(
containingDeclaration, kind, psiClass, fqName, this)
.getResolverBinaryClassData();
classDescriptorCache.put(fqName, classData);
classData.getClassDescriptor().setName(name);
List<JetType> supertypes = new ArrayList<JetType>();
List<JavaDescriptorSignatureResolver.TypeParameterDescriptorInitialization> typeParameterDescriptorInitializations
= javaDescriptorSignatureResolver.createUninitializedClassTypeParameters(psiClass, classData);
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>();
for (JavaDescriptorSignatureResolver.TypeParameterDescriptorInitialization typeParameter : typeParameterDescriptorInitializations) {
typeParameters.add(typeParameter.descriptor);
}
classData.getClassDescriptor().setTypeParameterDescriptors(typeParameters);
classData.getClassDescriptor().setSupertypes(supertypes);
classData.getClassDescriptor().setVisibility(resolveVisibility(psiClass, jetClassAnnotation));
Modality modality;
if (classData.getClassDescriptor().getKind() == ClassKind.ANNOTATION_CLASS) {
modality = Modality.FINAL;
}
else {
modality = Modality.convertFromFlags(
psiClass.hasModifierProperty(PsiModifier.ABSTRACT) || psiClass.isInterface(),
!psiClass.hasModifierProperty(PsiModifier.FINAL));
}
classData.getClassDescriptor().setModality(modality);
classData.getClassDescriptor().createTypeConstructor();
classData.getClassDescriptor().setScopeForMemberLookup(new JavaClassMembersScope(semanticServices, classData));
javaDescriptorSignatureResolver.initializeTypeParameters(typeParameterDescriptorInitializations, classData.getClassDescriptor(), "class " + qualifiedName);
// TODO: ugly hack: tests crash if initializeTypeParameters called with class containing proper supertypes
List<TypeParameterDescriptor> classTypeParameters = classData.getClassDescriptor().getTypeConstructor().getParameters();
supertypes.addAll(getSupertypes(new PsiClassWrapper(psiClass), classData, classTypeParameters));
MutableClassDescriptorLite classObject = createClassObjectDescriptor(classData.getClassDescriptor(), psiClass);
if (classObject != null) {
classData.getClassDescriptor().getBuilder().setClassObjectDescriptor(classObject);
}
classData.getClassDescriptor().setAnnotations(resolveAnnotations(psiClass, taskList));
trace.record(BindingContext.CLASS, psiClass, classData.getClassDescriptor());
return classData;
public Map<FqNameBase, ResolverClassData> getClassDescriptorCache() {
return classDescriptorCache;
}
private static ClassKind getClassKind(@NotNull PsiClass psiClass, @NotNull JetClassAnnotation jetClassAnnotation) {
if (psiClass.isInterface()) {
return (psiClass.isAnnotationType() ? ClassKind.ANNOTATION_CLASS : ClassKind.TRAIT);
}
else {
if (psiClass.isEnum()) {
return ClassKind.ENUM_CLASS;
}
else {
return jetClassAnnotation.kind() == JvmStdlibNames.FLAG_CLASS_KIND_OBJECT ? ClassKind.OBJECT : ClassKind.CLASS;
}
}
public JavaDescriptorSignatureResolver getJavaDescriptorSignatureResolver() {
return javaDescriptorSignatureResolver;
}
public JavaSemanticServices getSemanticServices() {
return semanticServices;
}
public BindingTrace getTrace() {
return trace;
}
@NotNull
@@ -446,7 +334,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
return constructorDescriptor;
}
static void checkPsiClassIsNotJet(PsiClass psiClass) {
public static void checkPsiClassIsNotJet(PsiClass psiClass) {
if (psiClass instanceof JetJavaMirrorMarker) {
throw new IllegalStateException("trying to resolve fake jet PsiClass as regular PsiClass: " + psiClass.getQualifiedName());
}
@@ -467,7 +355,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
//* @see #createJavaNamespaceDescriptor(PsiClass)
*/
@Nullable
private MutableClassDescriptorLite createClassObjectDescriptor(@NotNull ClassDescriptor containing, @NotNull PsiClass psiClass) {
public MutableClassDescriptorLite createClassObjectDescriptor(@NotNull ClassDescriptor containing, @NotNull PsiClass psiClass) {
checkPsiClassIsNotJet(psiClass);
if (psiClass.isEnum()) {
@@ -567,7 +455,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
@NotNull
private ClassOrNamespaceDescriptor resolveParentDescriptor(@NotNull PsiClass psiClass) {
public ClassOrNamespaceDescriptor resolveParentDescriptor(@NotNull PsiClass psiClass) {
final String qualifiedName = psiClass.getQualifiedName();
assert qualifiedName != null;
FqName fqName = new FqName(qualifiedName);
@@ -577,7 +465,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
final String containingClassQualifiedName = containingClass.getQualifiedName();
assert containingClassQualifiedName != null;
FqName containerFqName = new FqName(containingClassQualifiedName);
ClassDescriptor clazz = resolveClass(containerFqName, DescriptorSearchRule.INCLUDE_KOTLIN);
ClassDescriptor clazz = classResolver.resolveClass(containerFqName, DescriptorSearchRule.INCLUDE_KOTLIN);
if (clazz == null) {
throw new IllegalStateException("PsiClass not found by name " + containerFqName + ", required to be container declaration of " + fqName);
}
@@ -598,7 +486,11 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
return ns;
}
private Collection<JetType> getSupertypes(PsiClassWrapper psiClass, ResolverClassData classData, List<TypeParameterDescriptor> typeParameters) {
public Collection<JetType> getSupertypes(
PsiClassWrapper psiClass,
ResolverClassData classData,
List<TypeParameterDescriptor> typeParameters
) {
ClassDescriptor classDescriptor = classData.getClassDescriptor();
final List<JetType> result = new ArrayList<JetType>();
@@ -1175,7 +1067,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
return (methodName.equals("values") && methodTypeParameters.isEmpty());
}
private List<AnnotationDescriptor> resolveAnnotations(PsiModifierListOwner owner, @NotNull List<Runnable> tasks) {
public List<AnnotationDescriptor> resolveAnnotations(PsiModifierListOwner owner, @NotNull List<Runnable> tasks) {
PsiAnnotation[] psiAnnotations = getAllAnnotations(owner);
List<AnnotationDescriptor> r = Lists.newArrayListWithCapacity(psiAnnotations.length);
for (PsiAnnotation psiAnnotation : psiAnnotations) {
@@ -1210,7 +1102,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
}
FqName annotationFqName = new FqName(qname);
final ClassDescriptor clazz = resolveClass(annotationFqName, DescriptorSearchRule.INCLUDE_KOTLIN, taskList);
final ClassDescriptor clazz = classResolver.resolveClass(annotationFqName, DescriptorSearchRule.INCLUDE_KOTLIN, taskList);
if (clazz == null) {
return null;
}
@@ -1301,7 +1193,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
PsiAnnotationMemberValue[] initializers = value.getInitializers();
List<CompileTimeConstant<?>> values = getCompileTimeConstantForArrayValues(annotationFqName, valueName, taskList, initializers);
ClassDescriptor classDescriptor = resolveClass(annotationFqName, DescriptorSearchRule.INCLUDE_KOTLIN, taskList);
ClassDescriptor classDescriptor = classResolver.resolveClass(annotationFqName, DescriptorSearchRule.INCLUDE_KOTLIN, taskList);
ValueParameterDescriptor valueParameterDescriptor = getValueParameterDescriptorForAnnotationParameter(valueName, classDescriptor);
if (valueParameterDescriptor == null) {
@@ -1342,7 +1234,8 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
}
JetScope scope;
ClassDescriptor classDescriptor = resolveClass(new FqName(fqName), DescriptorSearchRule.INCLUDE_KOTLIN, taskList);
ClassDescriptor classDescriptor =
classResolver.resolveClass(new FqName(fqName), DescriptorSearchRule.INCLUDE_KOTLIN, taskList);
if (classDescriptor == null) {
return null;
}
@@ -1527,7 +1420,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
private ClassDescriptor resolveInnerClass(@NotNull PsiClass innerPsiClass) {
String name = innerPsiClass.getQualifiedName();
assert name != null : "Inner class has no qualified name";
ClassDescriptor classDescriptor = resolveClass(new FqName(name), DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN);
ClassDescriptor classDescriptor = classResolver.resolveClass(new FqName(name), DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN);
assert classDescriptor != null : "Couldn't resolve class " + name;
return classDescriptor;
}
@@ -66,8 +66,8 @@ public class JavaDescriptorSignatureResolver {
@NotNull
private final TypeParameterDescriptorOrigin origin;
@NotNull
final TypeParameterDescriptorImpl descriptor;
final PsiTypeParameter psiTypeParameter;
private final TypeParameterDescriptorImpl descriptor;
private final PsiTypeParameter psiTypeParameter;
@Nullable
private final List<JetType> upperBoundsForKotlin;
@@ -87,6 +87,11 @@ public class JavaDescriptorSignatureResolver {
this.psiTypeParameter = psiTypeParameter;
this.upperBoundsForKotlin = upperBoundsForKotlin;
}
@NotNull
public TypeParameterDescriptorImpl getDescriptor() {
return descriptor;
}
}
@@ -298,7 +303,11 @@ public class JavaDescriptorSignatureResolver {
typeParameterDescriptor.setInitialized();
}
void initializeTypeParameters(List<TypeParameterDescriptorInitialization> typeParametersInitialization, @NotNull DeclarationDescriptor typeParametersOwner, @NotNull String context) {
public void initializeTypeParameters(
List<TypeParameterDescriptorInitialization> typeParametersInitialization,
@NotNull DeclarationDescriptor typeParametersOwner,
@NotNull String context
) {
List<TypeParameterDescriptor> prevTypeParameters = Lists.newArrayList();
List<TypeParameterDescriptor> typeParameters = Lists.newArrayList();
@@ -314,7 +323,10 @@ public class JavaDescriptorSignatureResolver {
}
List<TypeParameterDescriptorInitialization> createUninitializedClassTypeParameters(PsiClass psiClass, ResolverClassData classData) {
public List<TypeParameterDescriptorInitialization> createUninitializedClassTypeParameters(
PsiClass psiClass,
ResolverClassData classData
) {
JetClassAnnotation jetClassAnnotation = JetClassAnnotation.get(psiClass);
if (jetClassAnnotation.signature().length() > 0) {
@@ -0,0 +1,202 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.resolve.java.resolver;
import com.google.common.collect.Lists;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiModifier;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.*;
import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode;
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation;
import org.jetbrains.jet.lang.resolve.java.scope.JavaClassMembersScope;
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiClassWrapper;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType;
import java.util.ArrayList;
import java.util.List;
public class ClassResolver {
private final JavaDescriptorResolver javaDescriptorResolver;
public ClassResolver(JavaDescriptorResolver javaDescriptorResolver) {
this.javaDescriptorResolver = javaDescriptorResolver;
}
@Nullable
public ClassDescriptor resolveClass(@NotNull FqName qualifiedName, @NotNull DescriptorSearchRule searchRule) {
List<Runnable> tasks = Lists.newArrayList();
ClassDescriptor clazz = resolveClass(qualifiedName, searchRule, tasks);
for (Runnable task : tasks) {
task.run();
}
return clazz;
}
public ClassDescriptor resolveClass(@NotNull FqName qualifiedName) {
return resolveClass(qualifiedName, DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
}
public ClassDescriptor resolveClass(
@NotNull FqName qualifiedName,
@NotNull DescriptorSearchRule searchRule,
@NotNull List<Runnable> tasks
) {
if (qualifiedName.getFqName().endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) {
// TODO: only if -$$TImpl class is created by Kotlin
return null;
}
ClassDescriptor builtinClassDescriptor =
javaDescriptorResolver.getSemanticServices().getKotlinBuiltinClassDescriptor(qualifiedName);
if (builtinClassDescriptor != null) {
return builtinClassDescriptor;
}
// First, let's check that this is a real Java class, not a Java's view on a Kotlin class:
ClassDescriptor kotlinClassDescriptor = javaDescriptorResolver.getSemanticServices().getKotlinClassDescriptor(qualifiedName);
if (kotlinClassDescriptor != null) {
if (searchRule == DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN) {
throw new IllegalStateException("class must not be found in kotlin: " + qualifiedName);
}
else if (searchRule == DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN) {
return null;
}
else if (searchRule == DescriptorSearchRule.INCLUDE_KOTLIN) {
return kotlinClassDescriptor;
}
else {
throw new IllegalStateException("unknown searchRule: " + searchRule);
}
}
// Not let's take a descriptor of a Java class
JavaDescriptorResolveData.ResolverClassData classData = javaDescriptorResolver.getClassDescriptorCache().get(qualifiedName);
if (classData == null) {
PsiClass psiClass =
javaDescriptorResolver.getPsiClassFinder().findPsiClass(qualifiedName, PsiClassFinder.RuntimeClassesHandleMode.THROW);
if (psiClass == null) {
JavaDescriptorResolveData.ResolverClassData oldValue =
javaDescriptorResolver.getClassDescriptorCache().put(qualifiedName, JavaDescriptorResolveData.ResolverBinaryClassData.NEGATIVE);
if (oldValue != null) {
throw new IllegalStateException("rewrite at " + qualifiedName);
}
return null;
}
classData = createJavaClassDescriptor(psiClass, tasks);
}
return classData.getClassDescriptor();
}
@NotNull
public JavaDescriptorResolveData.ResolverClassData createJavaClassDescriptor(
@NotNull final PsiClass psiClass,
List<Runnable> taskList
) {
final String qualifiedName = psiClass.getQualifiedName();
assert qualifiedName != null;
FqName fqName = new FqName(qualifiedName);
if (javaDescriptorResolver.getClassDescriptorCache().containsKey(fqName)) {
throw new IllegalStateException(qualifiedName);
}
JavaDescriptorResolver.checkPsiClassIsNotJet(psiClass);
Name name = Name.identifier(psiClass.getName());
JetClassAnnotation jetClassAnnotation = JetClassAnnotation.get(psiClass);
ClassKind kind = getClassKind(psiClass, jetClassAnnotation);
ClassOrNamespaceDescriptor containingDeclaration = javaDescriptorResolver.resolveParentDescriptor(psiClass);
// class may be resolved during resolution of parent
JavaDescriptorResolveData.ResolverClassData classData = javaDescriptorResolver.getClassDescriptorCache().get(fqName);
if (classData != null) {
return classData;
}
classData = new ClassDescriptorFromJvmBytecode(
containingDeclaration, kind, psiClass, fqName, javaDescriptorResolver)
.getResolverBinaryClassData();
javaDescriptorResolver.getClassDescriptorCache().put(fqName, classData);
classData.getClassDescriptor().setName(name);
List<JetType> supertypes = new ArrayList<JetType>();
List<JavaDescriptorSignatureResolver.TypeParameterDescriptorInitialization> typeParameterDescriptorInitializations
= javaDescriptorResolver.getJavaDescriptorSignatureResolver().createUninitializedClassTypeParameters(psiClass, classData);
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>();
for (JavaDescriptorSignatureResolver.TypeParameterDescriptorInitialization typeParameter : typeParameterDescriptorInitializations) {
typeParameters.add(typeParameter.getDescriptor());
}
classData.getClassDescriptor().setTypeParameterDescriptors(typeParameters);
classData.getClassDescriptor().setSupertypes(supertypes);
classData.getClassDescriptor().setVisibility(JavaDescriptorResolver.resolveVisibility(psiClass, jetClassAnnotation));
Modality modality;
if (classData.getClassDescriptor().getKind() == ClassKind.ANNOTATION_CLASS) {
modality = Modality.FINAL;
}
else {
modality = Modality.convertFromFlags(
psiClass.hasModifierProperty(PsiModifier.ABSTRACT) || psiClass.isInterface(),
!psiClass.hasModifierProperty(PsiModifier.FINAL));
}
classData.getClassDescriptor().setModality(modality);
classData.getClassDescriptor().createTypeConstructor();
classData.getClassDescriptor()
.setScopeForMemberLookup(new JavaClassMembersScope(javaDescriptorResolver.getSemanticServices(), classData));
javaDescriptorResolver.getJavaDescriptorSignatureResolver()
.initializeTypeParameters(typeParameterDescriptorInitializations, classData.getClassDescriptor(), "class " + qualifiedName);
// TODO: ugly hack: tests crash if initializeTypeParameters called with class containing proper supertypes
List<TypeParameterDescriptor> classTypeParameters = classData.getClassDescriptor().getTypeConstructor().getParameters();
supertypes.addAll(javaDescriptorResolver.getSupertypes(new PsiClassWrapper(psiClass), classData, classTypeParameters));
MutableClassDescriptorLite classObject =
javaDescriptorResolver.createClassObjectDescriptor(classData.getClassDescriptor(), psiClass);
if (classObject != null) {
classData.getClassDescriptor().getBuilder().setClassObjectDescriptor(classObject);
}
classData.getClassDescriptor().setAnnotations(javaDescriptorResolver.resolveAnnotations(psiClass, taskList));
javaDescriptorResolver.getTrace().record(BindingContext.CLASS, psiClass, classData.getClassDescriptor());
return classData;
}
public static ClassKind getClassKind(@NotNull PsiClass psiClass, @NotNull JetClassAnnotation jetClassAnnotation) {
if (psiClass.isInterface()) {
return (psiClass.isAnnotationType() ? ClassKind.ANNOTATION_CLASS : ClassKind.TRAIT);
}
else {
if (psiClass.isEnum()) {
return ClassKind.ENUM_CLASS;
}
else {
return jetClassAnnotation.kind() == JvmStdlibNames.FLAG_CLASS_KIND_OBJECT ? ClassKind.OBJECT : ClassKind.CLASS;
}
}
}
}