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
public static MembersCache buildMembersByNameCache(
@Nullable PsiClass psiClass,
@NotNull MembersCache membersCache, @Nullable PsiClass psiClass,
@Nullable PsiPackage psiPackage,
boolean staticMembers,
boolean isKotlin
) {
MembersCache cache = new MembersCache();
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();
cache.new ObjectClassProcessor(classes).process();
return cache;
membersCache.new ObjectClassProcessor(classes).process();
return membersCache;
}
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 org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.name.FqName;
/**
* @author Pavel Talanov
*/
public class ResolverClassData extends ResolverScopeData {
public class ResolverClassData extends ClassPsiDeclarationProviderBase {
private ResolverClassData(
protected ResolverClassData(
@NotNull PsiClass psiClass,
@Nullable FqName fqName,
boolean staticMembers
) {
super(psiClass, null, fqName, staticMembers);
super(staticMembers, psiClass);
}
@NotNull
public static ResolverClassData createSyntheticClassObjectClassData(
@NotNull PsiClass psiClass
) {
return new ResolverClassData(psiClass, null, true);
return new ResolverClassData(psiClass, true);
}
public static ResolverClassData createBinaryClassData(
@NotNull PsiClass psiClass,
@Nullable FqName fqName
@NotNull PsiClass psiClass
) {
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 org.jetbrains.annotations.NotNull;
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.Name;
/**
* Either package or class with static members
*/
public class ResolverNamespaceData extends ResolverScopeData implements PackagePsiDeclarationProvider {
import static org.jetbrains.jet.lang.resolve.java.data.Origin.JAVA;
public ResolverNamespaceData(
public class ResolverNamespaceData extends PsiDeclarationProviderBase implements PackagePsiDeclarationProvider {
@NotNull
public static PackagePsiDeclarationProvider createDeclarationProviderForPackage(
@NotNull PsiPackage psiPackage,
@Nullable PsiClass psiClass,
@Nullable PsiPackage psiPackage,
@NotNull FqName fqName
//TODO:
@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;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiPackage;
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.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.MembersCache;
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;
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;
public abstract class ResolverScopeData extends ClassPsiDeclarationProviderBase {
@Nullable
private final PsiPackage psiPackage;
private final boolean staticMembers;
@NotNull
private final Origin origin;
public ResolverScopeData(
@Nullable PsiClass psiClass,
@Nullable PsiPackage psiPackage,
@Nullable FqName fqName,
boolean staticMembers
) {
super(staticMembers, psiClass);
DescriptorResolverUtils.checkPsiClassIsNotJet(psiClass);
this.psiClass = psiClass;
this.psiPackage = psiPackage;
if (psiClass == null && psiPackage == 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
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
public PsiPackage getPsiPackage() {
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();
assert qualifiedName != null;
FqName fqName = new FqName(qualifiedName);
ResolverClassData classObjectData = ResolverClassData.createBinaryClassData(classObjectPsiClass, fqName);
ResolverClassData classObjectData = ResolverClassData.createBinaryClassData(classObjectPsiClass);
ClassDescriptorFromJvmBytecode classObjectDescriptor
= new ClassDescriptorFromJvmBytecode(containing, ClassKind.CLASS_OBJECT, javaDescriptorResolver, classObjectData);
classObjectDescriptor.setSupertypes(supertypesResolver.getSupertypes(classObjectDescriptor, new PsiClassWrapper(classObjectPsiClass), classObjectData,
@@ -152,7 +152,7 @@ public final class JavaClassObjectResolver {
) {
FqNameUnsafe fqName = DescriptorResolverUtils.getFqNameForClassObject(psiClass);
ResolverClassData classData = ResolverClassData.createBinaryClassData(psiClass, null);
ResolverClassData classData = ResolverClassData.createBinaryClassData(psiClass);
ClassDescriptorFromJvmBytecode classObjectDescriptor = new ClassDescriptorFromJvmBytecode(
containing, ClassKind.CLASS_OBJECT, javaDescriptorResolver, classData);
@@ -224,7 +224,7 @@ public final class JavaClassResolver {
) {
JetClassAnnotation jetClassAnnotation = JetClassAnnotation.get(psiClass);
ClassKind kind = getClassKind(psiClass, jetClassAnnotation);
ResolverClassData classData = ResolverClassData.createBinaryClassData(psiClass, fqName);
ResolverClassData classData = ResolverClassData.createBinaryClassData(psiClass);
ClassDescriptorFromJvmBytecode classDescriptor
= new ClassDescriptorFromJvmBytecode(containingDeclaration, kind, javaDescriptorResolver, classData);
@@ -106,7 +106,7 @@ public final class JavaNamespaceResolver {
return null;
}
trace.record(BindingContext.NAMESPACE, newScope.getResolverScopeData().getPsiPackageOrPsiClass(), javaNamespaceDescriptor);
trace.record(BindingContext.NAMESPACE, newScope.getResolverScopeData().getPsiPackage(), javaNamespaceDescriptor);
javaNamespaceDescriptor.setMemberScope(newScope);
@@ -173,7 +173,8 @@ public final class JavaNamespaceResolver {
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) {
@@ -42,10 +42,6 @@ public class JavaPackageScope extends JavaBaseScope {
@NotNull ResolverScopeData resolverNamespaceData) {
super(descriptor, semanticServices, resolverNamespaceData);
this.packageFQN = packageFQN;
if (!resolverNamespaceData.isStaticMembers()) {
throw new IllegalArgumentException("instance members should be resolved using " + JavaClassMembersScope.class);
}
}
@Override