Refactor: restructure Resolver*Data class hierarchy

Compilation errors still present
This commit is contained in:
Pavel V. Talanov
2012-11-05 12:20:17 +04:00
parent 89c5bef6eb
commit 5405b03f21
11 changed files with 223 additions and 101 deletions
@@ -56,18 +56,17 @@ public final class MembersCache {
@NotNull @NotNull
public static MembersCache buildMembersByNameCache( public static MembersCache buildMembersByNameCache(
@Nullable PsiClass psiClass, @NotNull MembersCache membersCache, @Nullable PsiClass psiClass,
@Nullable PsiPackage psiPackage, @Nullable PsiPackage psiPackage,
boolean staticMembers, boolean staticMembers,
boolean isKotlin boolean isKotlin
) { ) {
MembersCache cache = new MembersCache();
if (psiClass != null) { if (psiClass != null) {
cache.new ClassMemberProcessor(new PsiClassWrapper(psiClass), staticMembers, isKotlin).process(); membersCache.new ClassMemberProcessor(new PsiClassWrapper(psiClass), staticMembers, isKotlin).process();
} }
PsiClass[] classes = psiPackage != null ? psiPackage.getClasses() : psiClass.getInnerClasses(); PsiClass[] classes = psiPackage != null ? psiPackage.getClasses() : psiClass.getInnerClasses();
cache.new ObjectClassProcessor(classes).process(); membersCache.new ObjectClassProcessor(classes).process();
return cache; return membersCache;
} }
private class ObjectClassProcessor { private class ObjectClassProcessor {
@@ -0,0 +1,60 @@
package org.jetbrains.jet.lang.resolve.java.data;
import com.intellij.psi.PsiClass;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils;
import org.jetbrains.jet.lang.resolve.java.MembersCache;
import static org.jetbrains.jet.lang.resolve.java.data.Origin.JAVA;
import static org.jetbrains.jet.lang.resolve.java.data.Origin.KOTLIN;
public abstract class ClassPsiDeclarationProviderBase extends PsiDeclarationProviderBase implements ClassPsiDeclarationProvider {
@NotNull
private final PsiClass psiClass;
private final boolean staticMembers;
@NotNull
protected final Origin origin;
public ClassPsiDeclarationProviderBase(
boolean staticMembers,
@NotNull PsiClass psiClass
) {
this.staticMembers = staticMembers;
this.psiClass = psiClass;
this.origin = determineOrigin(psiClass);
}
@Override
@NotNull
protected MembersCache buildMembersCache() {
return MembersCache.buildMembersByNameCache(new MembersCache(), psiClass, null, staticMembers, getOrigin() == KOTLIN);
}
@Override
@NotNull
public PsiClass getPsiClass() {
return psiClass;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
@NotNull
public Origin getOrigin() {
return origin;
}
@NotNull
private static Origin determineOrigin(@Nullable PsiClass psiClass) {
return ((psiClass != null) && DescriptorResolverUtils.isKotlinClass(psiClass)) ? KOTLIN : JAVA;
}
public boolean isStaticMembers() {
return staticMembers;
}
}
@@ -0,0 +1,58 @@
/*
* 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.data;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiPackage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.java.MembersCache;
import static org.jetbrains.jet.lang.resolve.java.data.Origin.KOTLIN;
public final class KotlinNamespacePsiDeclarationProvider extends ResolverClassData implements PackagePsiDeclarationProvider {
@NotNull
private final PackagePsiDeclarationProvider packagePsiDeclarationProvider;
public KotlinNamespacePsiDeclarationProvider(
@NotNull PsiPackage psiPackage,
@NotNull PsiClass psiClass
) {
super(psiClass, true);
this.packagePsiDeclarationProvider = new ResolverNamespaceData(psiPackage);
}
@NotNull
@Override
public PsiPackage getPsiPackage() {
return packagePsiDeclarationProvider.getPsiPackage();
}
@NotNull
@Override
protected MembersCache buildMembersCache() {
MembersCache cacheWithMembers = super.buildMembersCache();
MembersCache.buildMembersByNameCache(cacheWithMembers, null, packagePsiDeclarationProvider.getPsiPackage(), true, getOrigin() == KOTLIN);
return cacheWithMembers;
}
@NotNull
@Override
public Origin getOrigin() {
return KOTLIN;
}
}
@@ -0,0 +1,36 @@
/*
* 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.data;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.java.MembersCache;
public abstract class PsiDeclarationProviderBase implements PsiDeclarationProvider {
private MembersCache membersCache = null;
@Override
@NotNull
public MembersCache getMembersCache() {
if (membersCache == null) {
membersCache = buildMembersCache();
}
return membersCache;
}
@NotNull
protected abstract MembersCache buildMembersCache();
}
@@ -18,33 +18,29 @@ package org.jetbrains.jet.lang.resolve.java.data;
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.resolve.name.FqName;
/** /**
* @author Pavel Talanov * @author Pavel Talanov
*/ */
public class ResolverClassData extends ResolverScopeData { public class ResolverClassData extends ClassPsiDeclarationProviderBase {
private ResolverClassData( protected ResolverClassData(
@NotNull PsiClass psiClass, @NotNull PsiClass psiClass,
@Nullable FqName fqName,
boolean staticMembers boolean staticMembers
) { ) {
super(psiClass, null, fqName, staticMembers); super(staticMembers, psiClass);
} }
@NotNull @NotNull
public static ResolverClassData createSyntheticClassObjectClassData( public static ResolverClassData createSyntheticClassObjectClassData(
@NotNull PsiClass psiClass @NotNull PsiClass psiClass
) { ) {
return new ResolverClassData(psiClass, null, true); return new ResolverClassData(psiClass, true);
} }
public static ResolverClassData createBinaryClassData( public static ResolverClassData createBinaryClassData(
@NotNull PsiClass psiClass, @NotNull PsiClass psiClass
@Nullable FqName fqName
) { ) {
return new ResolverClassData(psiClass, fqName, false); return new ResolverClassData(psiClass, false);
} }
} }
@@ -20,18 +20,61 @@ import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiPackage; import com.intellij.psi.PsiPackage;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.MembersCache;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
/** import static org.jetbrains.jet.lang.resolve.java.data.Origin.JAVA;
* Either package or class with static members
*/
public class ResolverNamespaceData extends ResolverScopeData implements PackagePsiDeclarationProvider {
public ResolverNamespaceData( public class ResolverNamespaceData extends PsiDeclarationProviderBase implements PackagePsiDeclarationProvider {
@NotNull
public static PackagePsiDeclarationProvider createDeclarationProviderForPackage(
@NotNull PsiPackage psiPackage,
@Nullable PsiClass psiClass, @Nullable PsiClass psiClass,
@Nullable PsiPackage psiPackage, //TODO:
@NotNull FqName fqName @Nullable FqName fqName
) { ) {
super(psiClass, psiPackage, fqName, true); if (psiClass == null) {
return new ResolverNamespaceData(psiPackage);
}
KotlinNamespacePsiDeclarationProvider result = new KotlinNamespacePsiDeclarationProvider(psiPackage, psiClass);
if (fqName != null && fqName.lastSegmentIs(Name.identifier(JvmAbi.PACKAGE_CLASS))) {
throw new IllegalStateException("Kotlin namespace cannot have last segment " + JvmAbi.PACKAGE_CLASS + ": " + fqName);
}
return result;
}
@NotNull
private final PsiPackage psiPackage;
protected ResolverNamespaceData(
@NotNull PsiPackage psiPackage
) {
this.psiPackage = psiPackage;
}
@NotNull
@Override
public PsiPackage getPsiPackage() {
return psiPackage;
}
@NotNull
@Override
protected MembersCache buildMembersCache() {
return MembersCache.buildMembersByNameCache(new MembersCache(), null, getPsiPackage(), true, false);
}
@NotNull
@Override
public Origin getOrigin() {
return JAVA;
}
@Override
public boolean isEmpty() {
return false;
} }
} }
@@ -17,104 +17,37 @@
package org.jetbrains.jet.lang.resolve.java.data; package org.jetbrains.jet.lang.resolve.java.data;
import com.intellij.psi.PsiClass; import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiPackage; import com.intellij.psi.PsiPackage;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils; import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.MembersCache;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import static org.jetbrains.jet.lang.resolve.java.data.Origin.JAVA; public abstract class ResolverScopeData extends ClassPsiDeclarationProviderBase {
import static org.jetbrains.jet.lang.resolve.java.data.Origin.KOTLIN;
public abstract class ResolverScopeData implements ClassPsiDeclarationProvider {
private MembersCache membersCache = null;
private final PsiClass psiClass;
@Nullable @Nullable
private final PsiPackage psiPackage; private final PsiPackage psiPackage;
private final boolean staticMembers;
@NotNull
private final Origin origin;
public ResolverScopeData( public ResolverScopeData(
@Nullable PsiClass psiClass, @Nullable PsiClass psiClass,
@Nullable PsiPackage psiPackage, @Nullable PsiPackage psiPackage,
@Nullable FqName fqName, @Nullable FqName fqName,
boolean staticMembers boolean staticMembers
) { ) {
super(staticMembers, psiClass);
DescriptorResolverUtils.checkPsiClassIsNotJet(psiClass); DescriptorResolverUtils.checkPsiClassIsNotJet(psiClass);
this.psiClass = psiClass;
this.psiPackage = psiPackage; this.psiPackage = psiPackage;
if (psiClass == null && psiPackage == null) { if (psiClass == null && psiPackage == null) {
throw new IllegalStateException("both psiClass and psiPackage cannot be null"); throw new IllegalStateException("both psiClass and psiPackage cannot be null");
} }
this.staticMembers = staticMembers;
this.origin = determineOrigin(psiClass);
//TODO: move check to remove fqName parameter //TODO: move check to remove fqName parameter
if (fqName != null && fqName.lastSegmentIs(Name.identifier(JvmAbi.PACKAGE_CLASS)) && psiClass != null && getOrigin() == KOTLIN) {
throw new IllegalStateException("Kotlin namespace cannot have last segment " + JvmAbi.PACKAGE_CLASS + ": " + fqName);
}
}
@NotNull
private static Origin determineOrigin(@Nullable PsiClass psiClass) {
return ((psiClass != null) && DescriptorResolverUtils.isKotlinClass(psiClass)) ? KOTLIN : JAVA;
}
@NotNull
public PsiElement getPsiPackageOrPsiClass() {
if (psiPackage != null) {
return psiPackage;
}
else {
assert psiClass != null;
return psiClass;
}
}
@Override
@NotNull
public MembersCache getMembersCache() {
if (membersCache == null) {
membersCache = MembersCache.buildMembersByNameCache(psiClass, psiPackage, staticMembers, getOrigin() == KOTLIN);
}
return membersCache;
}
@Override
@NotNull
public PsiClass getPsiClass() {
return psiClass;
}
@Override
public boolean isEmpty() {
return psiClass == null;
} }
@NotNull @NotNull
public PsiPackage getPsiPackage() { public PsiPackage getPsiPackage() {
return psiPackage; return psiPackage;
} }
@Override
@NotNull
public Origin getOrigin() {
return origin;
}
public boolean isStaticMembers() {
return staticMembers;
}
} }
@@ -112,7 +112,7 @@ public final class JavaClassObjectResolver {
String qualifiedName = classObjectPsiClass.getQualifiedName(); String qualifiedName = classObjectPsiClass.getQualifiedName();
assert qualifiedName != null; assert qualifiedName != null;
FqName fqName = new FqName(qualifiedName); FqName fqName = new FqName(qualifiedName);
ResolverClassData classObjectData = ResolverClassData.createBinaryClassData(classObjectPsiClass, fqName); ResolverClassData classObjectData = ResolverClassData.createBinaryClassData(classObjectPsiClass);
ClassDescriptorFromJvmBytecode classObjectDescriptor ClassDescriptorFromJvmBytecode classObjectDescriptor
= new ClassDescriptorFromJvmBytecode(containing, ClassKind.CLASS_OBJECT, javaDescriptorResolver, classObjectData); = new ClassDescriptorFromJvmBytecode(containing, ClassKind.CLASS_OBJECT, javaDescriptorResolver, classObjectData);
classObjectDescriptor.setSupertypes(supertypesResolver.getSupertypes(classObjectDescriptor, new PsiClassWrapper(classObjectPsiClass), classObjectData, classObjectDescriptor.setSupertypes(supertypesResolver.getSupertypes(classObjectDescriptor, new PsiClassWrapper(classObjectPsiClass), classObjectData,
@@ -152,7 +152,7 @@ public final class JavaClassObjectResolver {
) { ) {
FqNameUnsafe fqName = DescriptorResolverUtils.getFqNameForClassObject(psiClass); FqNameUnsafe fqName = DescriptorResolverUtils.getFqNameForClassObject(psiClass);
ResolverClassData classData = ResolverClassData.createBinaryClassData(psiClass, null); ResolverClassData classData = ResolverClassData.createBinaryClassData(psiClass);
ClassDescriptorFromJvmBytecode classObjectDescriptor = new ClassDescriptorFromJvmBytecode( ClassDescriptorFromJvmBytecode classObjectDescriptor = new ClassDescriptorFromJvmBytecode(
containing, ClassKind.CLASS_OBJECT, javaDescriptorResolver, classData); containing, ClassKind.CLASS_OBJECT, javaDescriptorResolver, classData);
@@ -224,7 +224,7 @@ public final class JavaClassResolver {
) { ) {
JetClassAnnotation jetClassAnnotation = JetClassAnnotation.get(psiClass); JetClassAnnotation jetClassAnnotation = JetClassAnnotation.get(psiClass);
ClassKind kind = getClassKind(psiClass, jetClassAnnotation); ClassKind kind = getClassKind(psiClass, jetClassAnnotation);
ResolverClassData classData = ResolverClassData.createBinaryClassData(psiClass, fqName); ResolverClassData classData = ResolverClassData.createBinaryClassData(psiClass);
ClassDescriptorFromJvmBytecode classDescriptor ClassDescriptorFromJvmBytecode classDescriptor
= new ClassDescriptorFromJvmBytecode(containingDeclaration, kind, javaDescriptorResolver, classData); = new ClassDescriptorFromJvmBytecode(containingDeclaration, kind, javaDescriptorResolver, classData);
@@ -106,7 +106,7 @@ public final class JavaNamespaceResolver {
return null; return null;
} }
trace.record(BindingContext.NAMESPACE, newScope.getResolverScopeData().getPsiPackageOrPsiClass(), javaNamespaceDescriptor); trace.record(BindingContext.NAMESPACE, newScope.getResolverScopeData().getPsiPackage(), javaNamespaceDescriptor);
javaNamespaceDescriptor.setMemberScope(newScope); javaNamespaceDescriptor.setMemberScope(newScope);
@@ -173,7 +173,8 @@ public final class JavaNamespaceResolver {
return null; return null;
} }
return new ResolverNamespaceData(psiClass, psiPackage, fqName); assert psiPackage != null;
return ResolverNamespaceData.createDeclarationProviderForPackage(psiPackage, psiClass, fqName);
} }
private void cache(@NotNull FqName fqName, @Nullable JavaPackageScope packageScope) { private void cache(@NotNull FqName fqName, @Nullable JavaPackageScope packageScope) {
@@ -42,10 +42,6 @@ public class JavaPackageScope extends JavaBaseScope {
@NotNull ResolverScopeData resolverNamespaceData) { @NotNull ResolverScopeData resolverNamespaceData) {
super(descriptor, semanticServices, resolverNamespaceData); super(descriptor, semanticServices, resolverNamespaceData);
this.packageFQN = packageFQN; this.packageFQN = packageFQN;
if (!resolverNamespaceData.isStaticMembers()) {
throw new IllegalArgumentException("instance members should be resolved using " + JavaClassMembersScope.class);
}
} }
@Override @Override