Use validateFqName in FqName(String) constructor.
Fix JavaDescriptorResolver and JavaClassOrPackageScope accordingly.
This commit is contained in:
+2
-1
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve.java;
|
|||||||
|
|
||||||
import com.intellij.psi.PsiClass;
|
import com.intellij.psi.PsiClass;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassKind;
|
import org.jetbrains.jet.lang.descriptors.ClassKind;
|
||||||
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
@@ -44,7 +45,7 @@ public class ClassDescriptorFromJvmBytecode extends MutableClassDescriptorLite {
|
|||||||
|
|
||||||
public ClassDescriptorFromJvmBytecode(
|
public ClassDescriptorFromJvmBytecode(
|
||||||
@NotNull DeclarationDescriptor containingDeclaration, @NotNull ClassKind kind,
|
@NotNull DeclarationDescriptor containingDeclaration, @NotNull ClassKind kind,
|
||||||
@NotNull PsiClass psiClass, @NotNull FqName fqName,
|
@NotNull PsiClass psiClass, @Nullable FqName fqName,
|
||||||
@NotNull JavaDescriptorResolver javaDescriptorResolver) {
|
@NotNull JavaDescriptorResolver javaDescriptorResolver) {
|
||||||
super(containingDeclaration, kind);
|
super(containingDeclaration, kind);
|
||||||
this.javaDescriptorResolver = javaDescriptorResolver;
|
this.javaDescriptorResolver = javaDescriptorResolver;
|
||||||
|
|||||||
+2
-1
@@ -94,7 +94,8 @@ public abstract class JavaClassOrPackageScope extends JetScopeImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (resolverScopeData.psiPackage != null) {
|
if (resolverScopeData.psiPackage != null) {
|
||||||
boolean isKotlinNamespace = semanticServices.getKotlinNamespaceDescriptor(resolverScopeData.fqName) != null;
|
FqName packageFqName = resolverScopeData.fqName;
|
||||||
|
boolean isKotlinNamespace = packageFqName != null && semanticServices.getKotlinNamespaceDescriptor(packageFqName) != null;
|
||||||
final JavaDescriptorResolver descriptorResolver = semanticServices.getDescriptorResolver();
|
final JavaDescriptorResolver descriptorResolver = semanticServices.getDescriptorResolver();
|
||||||
|
|
||||||
for (PsiPackage psiSubPackage : resolverScopeData.psiPackage.getSubPackages()) {
|
for (PsiPackage psiSubPackage : resolverScopeData.psiPackage.getSubPackages()) {
|
||||||
|
|||||||
+31
-13
@@ -23,6 +23,8 @@ import com.intellij.codeInsight.ExternalAnnotationsManager;
|
|||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.util.Pair;
|
import com.intellij.openapi.util.Pair;
|
||||||
import com.intellij.psi.*;
|
import com.intellij.psi.*;
|
||||||
|
import gnu.trove.THashMap;
|
||||||
|
import gnu.trove.TObjectHashingStrategy;
|
||||||
import jet.typeinfo.TypeInfoVariance;
|
import jet.typeinfo.TypeInfoVariance;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -34,6 +36,8 @@ import org.jetbrains.jet.lang.resolve.constants.StringValue;
|
|||||||
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation;
|
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.kt.PsiAnnotationWithFlags;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
|
import org.jetbrains.jet.lang.resolve.name.FqNameBase;
|
||||||
|
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.*;
|
import org.jetbrains.jet.lang.resolve.scopes.*;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
@@ -85,13 +89,14 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
|||||||
final PsiClass psiClass;
|
final PsiClass psiClass;
|
||||||
@Nullable
|
@Nullable
|
||||||
final PsiPackage psiPackage;
|
final PsiPackage psiPackage;
|
||||||
|
@Nullable
|
||||||
final FqName fqName;
|
final FqName fqName;
|
||||||
final boolean staticMembers;
|
final boolean staticMembers;
|
||||||
final boolean kotlin;
|
final boolean kotlin;
|
||||||
final ClassOrNamespaceDescriptor classOrNamespaceDescriptor;
|
final ClassOrNamespaceDescriptor classOrNamespaceDescriptor;
|
||||||
private List<String> alternativeSignatureErrors;
|
private List<String> alternativeSignatureErrors;
|
||||||
|
|
||||||
protected ResolverScopeData(@Nullable PsiClass psiClass, @Nullable PsiPackage psiPackage, @NotNull FqName fqName, boolean staticMembers, @NotNull ClassOrNamespaceDescriptor descriptor) {
|
protected ResolverScopeData(@Nullable PsiClass psiClass, @Nullable PsiPackage psiPackage, @Nullable FqName fqName, boolean staticMembers, @NotNull ClassOrNamespaceDescriptor descriptor) {
|
||||||
checkPsiClassIsNotJet(psiClass);
|
checkPsiClassIsNotJet(psiClass);
|
||||||
|
|
||||||
this.psiClass = psiClass;
|
this.psiClass = psiClass;
|
||||||
@@ -107,7 +112,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
|||||||
(new PsiClassWrapper(psiClass).getJetClass().isDefined() || psiClass.getName().equals(JvmAbi.PACKAGE_CLASS));
|
(new PsiClassWrapper(psiClass).getJetClass().isDefined() || psiClass.getName().equals(JvmAbi.PACKAGE_CLASS));
|
||||||
classOrNamespaceDescriptor = descriptor;
|
classOrNamespaceDescriptor = descriptor;
|
||||||
|
|
||||||
if (fqName.lastSegmentIs(Name.identifier(JvmAbi.PACKAGE_CLASS)) && psiClass != null && kotlin) {
|
if (fqName != null && fqName.lastSegmentIs(Name.identifier(JvmAbi.PACKAGE_CLASS)) && psiClass != null && kotlin) {
|
||||||
throw new IllegalStateException("Kotlin namespace cannot have last segment " + JvmAbi.PACKAGE_CLASS + ": " + fqName);
|
throw new IllegalStateException("Kotlin namespace cannot have last segment " + JvmAbi.PACKAGE_CLASS + ": " + fqName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,7 +159,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
|||||||
/** Class with instance members */
|
/** Class with instance members */
|
||||||
static class ResolverBinaryClassData extends ResolverClassData {
|
static class ResolverBinaryClassData extends ResolverClassData {
|
||||||
|
|
||||||
ResolverBinaryClassData(@NotNull PsiClass psiClass, @NotNull FqName fqName, @NotNull ClassDescriptorFromJvmBytecode classDescriptor) {
|
ResolverBinaryClassData(@NotNull PsiClass psiClass, @Nullable FqName fqName, @NotNull ClassDescriptorFromJvmBytecode classDescriptor) {
|
||||||
super(psiClass, null, fqName, false, classDescriptor);
|
super(psiClass, null, fqName, false, classDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,7 +186,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
|||||||
protected ResolverClassData(
|
protected ResolverClassData(
|
||||||
@Nullable PsiClass psiClass,
|
@Nullable PsiClass psiClass,
|
||||||
@Nullable PsiPackage psiPackage,
|
@Nullable PsiPackage psiPackage,
|
||||||
@NotNull FqName fqName,
|
@Nullable FqName fqName,
|
||||||
boolean staticMembers,
|
boolean staticMembers,
|
||||||
@NotNull ClassDescriptorFromJvmBytecode descriptor
|
@NotNull ClassDescriptorFromJvmBytecode descriptor
|
||||||
) {
|
) {
|
||||||
@@ -207,7 +212,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
|||||||
|
|
||||||
protected ResolverEnumClassObjectClassData(
|
protected ResolverEnumClassObjectClassData(
|
||||||
@Nullable PsiClass psiClass,
|
@Nullable PsiClass psiClass,
|
||||||
@NotNull FqName fqName,
|
@Nullable FqName fqName,
|
||||||
@NotNull ClassDescriptorFromJvmBytecode descriptor
|
@NotNull ClassDescriptorFromJvmBytecode descriptor
|
||||||
) {
|
) {
|
||||||
super(psiClass, null, fqName, true, descriptor);
|
super(psiClass, null, fqName, true, descriptor);
|
||||||
@@ -239,7 +244,22 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final Map<FqName, ResolverClassData> classDescriptorCache = Maps.newHashMap();
|
// NOTE: this complexity is introduced because class descriptors do not always have valid fqnames (class objects)
|
||||||
|
protected final Map<FqNameBase, ResolverClassData> classDescriptorCache = new THashMap<FqNameBase, ResolverClassData>(new TObjectHashingStrategy<FqNameBase>() {
|
||||||
|
@Override
|
||||||
|
public int computeHashCode(FqNameBase o) {
|
||||||
|
if (o instanceof FqName) {
|
||||||
|
return ((FqName) o).toUnsafe().hashCode();
|
||||||
|
}
|
||||||
|
assert o instanceof FqNameUnsafe;
|
||||||
|
return o.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(FqNameBase n1, FqNameBase n2) {
|
||||||
|
return n1.equalsTo(n2.toString()) && n2.equalsTo(n1.toString());
|
||||||
|
}
|
||||||
|
});
|
||||||
protected final Map<FqName, ResolverNamespaceData> namespaceDescriptorCacheByFqn = Maps.newHashMap();
|
protected final Map<FqName, ResolverNamespaceData> namespaceDescriptorCacheByFqn = Maps.newHashMap();
|
||||||
|
|
||||||
protected Project project;
|
protected Project project;
|
||||||
@@ -572,8 +592,6 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
|||||||
containing, ClassKind.OBJECT, classObjectPsiClass, fqName, this)
|
containing, ClassKind.OBJECT, classObjectPsiClass, fqName, this)
|
||||||
.getResolverBinaryClassData();
|
.getResolverBinaryClassData();
|
||||||
|
|
||||||
classDescriptorCache.put(fqName, classData);
|
|
||||||
|
|
||||||
ClassDescriptorFromJvmBytecode classObjectDescriptor = classData.classDescriptor;
|
ClassDescriptorFromJvmBytecode classObjectDescriptor = classData.classDescriptor;
|
||||||
classObjectDescriptor.setSupertypes(
|
classObjectDescriptor.setSupertypes(
|
||||||
getSupertypes(new PsiClassWrapper(classObjectPsiClass), classData, new ArrayList<TypeParameterDescriptor>(0)));
|
getSupertypes(new PsiClassWrapper(classObjectPsiClass), classData, new ArrayList<TypeParameterDescriptor>(0)));
|
||||||
@@ -585,11 +603,11 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
|||||||
private MutableClassDescriptorLite createClassObjectDescriptorForEnum(@NotNull ClassDescriptor containing, @NotNull PsiClass psiClass) {
|
private MutableClassDescriptorLite createClassObjectDescriptorForEnum(@NotNull ClassDescriptor containing, @NotNull PsiClass psiClass) {
|
||||||
String psiClassQualifiedName = psiClass.getQualifiedName();
|
String psiClassQualifiedName = psiClass.getQualifiedName();
|
||||||
assert psiClassQualifiedName != null : "Reading java class with no qualified name";
|
assert psiClassQualifiedName != null : "Reading java class with no qualified name";
|
||||||
FqName fqName = new FqName(psiClassQualifiedName + "." + getClassObjectName(psiClass.getName()).getName());
|
FqNameUnsafe fqName = new FqNameUnsafe(psiClassQualifiedName + "." + getClassObjectName(psiClass.getName()).getName());
|
||||||
ClassDescriptorFromJvmBytecode classObjectDescriptor = new ClassDescriptorFromJvmBytecode(
|
ClassDescriptorFromJvmBytecode classObjectDescriptor = new ClassDescriptorFromJvmBytecode(
|
||||||
containing, ClassKind.OBJECT, psiClass, fqName, this);
|
containing, ClassKind.OBJECT, psiClass, null, this);
|
||||||
|
|
||||||
ResolverEnumClassObjectClassData data = new ResolverEnumClassObjectClassData(psiClass, fqName, classObjectDescriptor);
|
ResolverEnumClassObjectClassData data = new ResolverEnumClassObjectClassData(psiClass, null, classObjectDescriptor);
|
||||||
setUpClassObjectDescriptor(containing, fqName, data, getClassObjectName(containing.getName().getName()));
|
setUpClassObjectDescriptor(containing, fqName, data, getClassObjectName(containing.getName().getName()));
|
||||||
|
|
||||||
classObjectDescriptor.getBuilder().addFunctionDescriptor(createEnumClassObjectValuesMethod(classObjectDescriptor, trace));
|
classObjectDescriptor.getBuilder().addFunctionDescriptor(createEnumClassObjectValuesMethod(classObjectDescriptor, trace));
|
||||||
@@ -600,7 +618,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
|||||||
|
|
||||||
private void setUpClassObjectDescriptor(
|
private void setUpClassObjectDescriptor(
|
||||||
@NotNull ClassDescriptor containing,
|
@NotNull ClassDescriptor containing,
|
||||||
@NotNull FqName fqName,
|
@NotNull FqNameBase fqName,
|
||||||
@NotNull ResolverClassData data,
|
@NotNull ResolverClassData data,
|
||||||
@NotNull Name classObjectName
|
@NotNull Name classObjectName
|
||||||
) {
|
) {
|
||||||
@@ -612,7 +630,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
|||||||
classDescriptor.setTypeParameterDescriptors(Collections.<TypeParameterDescriptor>emptyList());
|
classDescriptor.setTypeParameterDescriptors(Collections.<TypeParameterDescriptor>emptyList());
|
||||||
classDescriptor.createTypeConstructor();
|
classDescriptor.createTypeConstructor();
|
||||||
JavaClassMembersScope classMembersScope = new JavaClassMembersScope(semanticServices, data);
|
JavaClassMembersScope classMembersScope = new JavaClassMembersScope(semanticServices, data);
|
||||||
WritableScopeImpl writableScope = new WritableScopeImpl(classMembersScope, classDescriptor, RedeclarationHandler.THROW_EXCEPTION, fqName.getFqName());
|
WritableScopeImpl writableScope = new WritableScopeImpl(classMembersScope, classDescriptor, RedeclarationHandler.THROW_EXCEPTION, fqName.toString());
|
||||||
writableScope.changeLockLevel(WritableScope.LockLevel.BOTH);
|
writableScope.changeLockLevel(WritableScope.LockLevel.BOTH);
|
||||||
classDescriptor.setScopeForMemberLookup(writableScope);
|
classDescriptor.setScopeForMemberLookup(writableScope);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ public class FqName extends FqNameBase {
|
|||||||
|
|
||||||
public FqName(@NotNull String fqName) {
|
public FqName(@NotNull String fqName) {
|
||||||
this.fqName = new FqNameUnsafe(fqName, this);
|
this.fqName = new FqNameUnsafe(fqName, this);
|
||||||
|
|
||||||
|
validateFqName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FqName(@NotNull FqNameUnsafe fqName) {
|
public FqName(@NotNull FqNameUnsafe fqName) {
|
||||||
|
|||||||
Reference in New Issue
Block a user