Refactoring: remove LightClassStubWithData, use generics for KotlinJavaFileStubProvider

This commit is contained in:
Nikolay Krasko
2013-12-30 16:15:46 +04:00
parent 623b169d71
commit e946f1abba
4 changed files with 49 additions and 44 deletions
@@ -56,18 +56,18 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
public class KotlinJavaFileStubProvider implements CachedValueProvider<LightClassStubWithData> { public class KotlinJavaFileStubProvider<T extends WithFileStub> implements CachedValueProvider<T> {
@NotNull @NotNull
public static KotlinJavaFileStubProvider createForPackageClass( public static KotlinJavaFileStubProvider<KotlinPackageLightClassData> createForPackageClass(
@NotNull final Project project, @NotNull final Project project,
@NotNull final FqName packageFqName, @NotNull final FqName packageFqName,
@NotNull final GlobalSearchScope searchScope @NotNull final GlobalSearchScope searchScope
) { ) {
return new KotlinJavaFileStubProvider( return new KotlinJavaFileStubProvider<KotlinPackageLightClassData>(
project, project,
false, false,
new StubGenerationStrategy.NoDeclaredClasses() { new StubGenerationStrategy.NoDeclaredClasses<KotlinPackageLightClassData>() {
@NotNull @NotNull
@Override @Override
public LightClassConstructionContext getContext(@NotNull Collection<JetFile> files) { public LightClassConstructionContext getContext(@NotNull Collection<JetFile> files) {
@@ -84,8 +84,8 @@ public class KotlinJavaFileStubProvider implements CachedValueProvider<LightClas
@NotNull @NotNull
@Override @Override
public LightClassStubWithData createLightClassStubWithData(PsiJavaFileStub javaFileStub, BindingContext bindingContext) { public KotlinPackageLightClassData createLightClassData(PsiJavaFileStub javaFileStub, BindingContext bindingContext) {
return new LightClassStubWithData(javaFileStub, KotlinPackageLightClassData.instance$); return new KotlinPackageLightClassData(javaFileStub);
} }
@NotNull @NotNull
@@ -105,11 +105,11 @@ public class KotlinJavaFileStubProvider implements CachedValueProvider<LightClas
} }
@NotNull @NotNull
public static KotlinJavaFileStubProvider createForDeclaredClass(@NotNull final JetClassOrObject classOrObject) { public static KotlinJavaFileStubProvider<OutermostKotlinClassLightClassData> createForDeclaredClass(@NotNull final JetClassOrObject classOrObject) {
return new KotlinJavaFileStubProvider( return new KotlinJavaFileStubProvider<OutermostKotlinClassLightClassData>(
classOrObject.getProject(), classOrObject.getProject(),
JetPsiUtil.isLocal(classOrObject), JetPsiUtil.isLocal(classOrObject),
new StubGenerationStrategy.WithDeclaredClasses() { new StubGenerationStrategy.WithDeclaredClasses<OutermostKotlinClassLightClassData>() {
private JetFile getFile() { private JetFile getFile() {
return (JetFile) classOrObject.getContainingFile(); return (JetFile) classOrObject.getContainingFile();
} }
@@ -122,19 +122,19 @@ public class KotlinJavaFileStubProvider implements CachedValueProvider<LightClas
@NotNull @NotNull
@Override @Override
public LightClassStubWithData createLightClassStubWithData(PsiJavaFileStub javaFileStub, BindingContext bindingContext) { public OutermostKotlinClassLightClassData createLightClassData(PsiJavaFileStub javaFileStub, BindingContext bindingContext) {
ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, classOrObject); ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, classOrObject);
if (classDescriptor == null) { if (classDescriptor == null) {
return new LightClassStubWithData( return new OutermostKotlinClassLightClassData(
javaFileStub, javaFileStub,
new OutermostKotlinClassLightClassData("", classOrObject, null, Collections.<JetClassOrObject, LightClassDataForKotlinClass>emptyMap()) "", classOrObject, null, Collections.<JetClassOrObject, InnerKotlinClassLightClassData>emptyMap()
); );
} }
String jvmInternalName = CodegenBinding.getJvmInternalName(bindingContext, classDescriptor); String jvmInternalName = CodegenBinding.getJvmInternalName(bindingContext, classDescriptor);
Collection<ClassDescriptor> allInnerClasses = CodegenBinding.getAllInnerClasses(bindingContext, classDescriptor); Collection<ClassDescriptor> allInnerClasses = CodegenBinding.getAllInnerClasses(bindingContext, classDescriptor);
Map<JetClassOrObject, LightClassDataForKotlinClass> innerClassesMap = ContainerUtil.newHashMap(); Map<JetClassOrObject, InnerKotlinClassLightClassData> innerClassesMap = ContainerUtil.newHashMap();
for (ClassDescriptor innerClassDescriptor : allInnerClasses) { for (ClassDescriptor innerClassDescriptor : allInnerClasses) {
JetClassOrObject innerClass = (JetClassOrObject) BindingContextUtils.descriptorToDeclaration( JetClassOrObject innerClass = (JetClassOrObject) BindingContextUtils.descriptorToDeclaration(
bindingContext, innerClassDescriptor bindingContext, innerClassDescriptor
@@ -146,12 +146,16 @@ public class KotlinJavaFileStubProvider implements CachedValueProvider<LightClas
innerClass, innerClass,
innerClassDescriptor innerClassDescriptor
); );
innerClassesMap.put(innerClass, innerLightClassData); innerClassesMap.put(innerClass, innerLightClassData);
} }
return new LightClassStubWithData( return new OutermostKotlinClassLightClassData(
javaFileStub, javaFileStub,
new OutermostKotlinClassLightClassData(jvmInternalName, classOrObject, classDescriptor, innerClassesMap) jvmInternalName,
classOrObject,
classDescriptor,
innerClassesMap
); );
} }
@@ -180,13 +184,13 @@ public class KotlinJavaFileStubProvider implements CachedValueProvider<LightClas
private static final Logger LOG = Logger.getInstance(KotlinJavaFileStubProvider.class); private static final Logger LOG = Logger.getInstance(KotlinJavaFileStubProvider.class);
private final Project project; private final Project project;
private final StubGenerationStrategy stubGenerationStrategy; private final StubGenerationStrategy<T> stubGenerationStrategy;
private final boolean local; private final boolean local;
private KotlinJavaFileStubProvider( private KotlinJavaFileStubProvider(
@NotNull Project project, @NotNull Project project,
boolean local, boolean local,
@NotNull StubGenerationStrategy stubGenerationStrategy @NotNull StubGenerationStrategy<T> stubGenerationStrategy
) { ) {
this.project = project; this.project = project;
this.stubGenerationStrategy = stubGenerationStrategy; this.stubGenerationStrategy = stubGenerationStrategy;
@@ -195,7 +199,7 @@ public class KotlinJavaFileStubProvider implements CachedValueProvider<LightClas
@Nullable @Nullable
@Override @Override
public Result<LightClassStubWithData> compute() { public Result<T> compute() {
FqName packageFqName = stubGenerationStrategy.getPackageFqName(); FqName packageFqName = stubGenerationStrategy.getPackageFqName();
Collection<JetFile> files = stubGenerationStrategy.getFiles(); Collection<JetFile> files = stubGenerationStrategy.getFiles();
@@ -242,8 +246,8 @@ public class KotlinJavaFileStubProvider implements CachedValueProvider<LightClas
throw e; throw e;
} }
return Result.<LightClassStubWithData>create( return Result.create(
stubGenerationStrategy.createLightClassStubWithData(javaFileStub, bindingContext), stubGenerationStrategy.createLightClassData(javaFileStub, bindingContext),
local ? PsiModificationTracker.MODIFICATION_COUNT : PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT local ? PsiModificationTracker.MODIFICATION_COUNT : PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT
); );
} }
@@ -302,16 +306,16 @@ public class KotlinJavaFileStubProvider implements CachedValueProvider<LightClas
cause); cause);
} }
private interface StubGenerationStrategy { private interface StubGenerationStrategy<T extends WithFileStub> {
@NotNull Collection<JetFile> getFiles(); @NotNull Collection<JetFile> getFiles();
@NotNull FqName getPackageFqName(); @NotNull FqName getPackageFqName();
@NotNull LightClassConstructionContext getContext(@NotNull Collection<JetFile> files); @NotNull LightClassConstructionContext getContext(@NotNull Collection<JetFile> files);
@NotNull LightClassStubWithData createLightClassStubWithData(PsiJavaFileStub javaFileStub, BindingContext bindingContext); @NotNull T createLightClassData(PsiJavaFileStub javaFileStub, BindingContext bindingContext);
boolean generateDeclaredClasses(); boolean generateDeclaredClasses();
void generate(@NotNull GenerationState state, @NotNull Collection<JetFile> files); void generate(@NotNull GenerationState state, @NotNull Collection<JetFile> files);
abstract class NoDeclaredClasses implements StubGenerationStrategy { abstract class NoDeclaredClasses<U extends WithFileStub> implements StubGenerationStrategy<U> {
@Override @Override
public boolean generateDeclaredClasses() { public boolean generateDeclaredClasses() {
return false; return false;
@@ -324,7 +328,7 @@ public class KotlinJavaFileStubProvider implements CachedValueProvider<LightClas
} }
} }
abstract class WithDeclaredClasses implements StubGenerationStrategy { abstract class WithDeclaredClasses<U extends WithFileStub> implements StubGenerationStrategy<U> {
@Override @Override
public boolean generateDeclaredClasses() { public boolean generateDeclaredClasses() {
return true; return true;
@@ -62,7 +62,7 @@ import java.util.List;
import static org.jetbrains.jet.lexer.JetTokens.*; import static org.jetbrains.jet.lexer.JetTokens.*;
public class KotlinLightClassForExplicitDeclaration extends KotlinWrappingLightClass implements KotlinLightClass, JetJavaMirrorMarker { public class KotlinLightClassForExplicitDeclaration extends KotlinWrappingLightClass implements KotlinLightClass, JetJavaMirrorMarker {
private final static Key<CachedValue<LightClassStubWithData>> JAVA_API_STUB = Key.create("JAVA_API_STUB"); private final static Key<CachedValue<OutermostKotlinClassLightClassData>> JAVA_API_STUB = Key.create("JAVA_API_STUB");
@Nullable @Nullable
public static KotlinLightClassForExplicitDeclaration create(@NotNull PsiManager manager, @NotNull JetClassOrObject classOrObject) { public static KotlinLightClassForExplicitDeclaration create(@NotNull PsiManager manager, @NotNull JetClassOrObject classOrObject) {
@@ -236,7 +236,7 @@ public class KotlinLightClassForExplicitDeclaration extends KotlinWrappingLightC
@NotNull @NotNull
private PsiJavaFileStub getJavaFileStub() { private PsiJavaFileStub getJavaFileStub() {
return getLightClassStubWithData().getJavaFileStub(); return getLightClassData().getJavaFileStub();
} }
@Nullable @Nullable
@@ -246,12 +246,12 @@ public class KotlinLightClassForExplicitDeclaration extends KotlinWrappingLightC
} }
@NotNull @NotNull
private LightClassStubWithData getLightClassStubWithData() { private OutermostKotlinClassLightClassData getLightClassData() {
return getLightClassStubWithData(classOrObject); return getLightClassData(classOrObject);
} }
@NotNull @NotNull
private static LightClassStubWithData getLightClassStubWithData(JetClassOrObject classOrObject) { private static OutermostKotlinClassLightClassData getLightClassData(JetClassOrObject classOrObject) {
JetClassOrObject outermostClassOrObject = getOutermostClassOrObject(classOrObject); JetClassOrObject outermostClassOrObject = getOutermostClassOrObject(classOrObject);
return CachedValuesManager.getManager(classOrObject.getProject()).getCachedValue( return CachedValuesManager.getManager(classOrObject.getProject()).getCachedValue(
outermostClassOrObject, outermostClassOrObject,
@@ -263,8 +263,7 @@ public class KotlinLightClassForExplicitDeclaration extends KotlinWrappingLightC
@Nullable @Nullable
private static LightClassDataForKotlinClass getLightClassDataExactly(JetClassOrObject classOrObject) { private static LightClassDataForKotlinClass getLightClassDataExactly(JetClassOrObject classOrObject) {
OutermostKotlinClassLightClassData data = OutermostKotlinClassLightClassData data = getLightClassData(classOrObject);
(OutermostKotlinClassLightClassData) getLightClassStubWithData(classOrObject).getClassData();
return data.getClassOrObject().equals(classOrObject) ? data : data.getAllInnerClasses().get(classOrObject); return data.getClassOrObject().equals(classOrObject) ? data : data.getAllInnerClasses().get(classOrObject);
} }
@@ -48,7 +48,7 @@ public class KotlinLightClassForPackage extends KotlinWrappingLightClass impleme
private final GlobalSearchScope searchScope; private final GlobalSearchScope searchScope;
private final Collection<JetFile> files; private final Collection<JetFile> files;
private final int hashCode; private final int hashCode;
private final CachedValue<LightClassStubWithData> javaFileStub; private final CachedValue<KotlinPackageLightClassData> lightClassDataCache;
private final PsiModifierList modifierList; private final PsiModifierList modifierList;
private final LightEmptyImplementsList implementsList; private final LightEmptyImplementsList implementsList;
@@ -67,9 +67,9 @@ public class KotlinLightClassForPackage extends KotlinWrappingLightClass impleme
assert !files.isEmpty() : "No files for package " + packageFqName; assert !files.isEmpty() : "No files for package " + packageFqName;
this.files = Sets.newHashSet(files); // needed for hashCode this.files = Sets.newHashSet(files); // needed for hashCode
this.hashCode = computeHashCode(); this.hashCode = computeHashCode();
KotlinJavaFileStubProvider stubProvider = KotlinJavaFileStubProvider<KotlinPackageLightClassData> stubProvider =
KotlinJavaFileStubProvider.createForPackageClass(getProject(), packageFqName, searchScope); KotlinJavaFileStubProvider.createForPackageClass(getProject(), packageFqName, searchScope);
this.javaFileStub = CachedValuesManager.getManager(getProject()).createCachedValue(stubProvider, /*trackValue = */false); this.lightClassDataCache = CachedValuesManager.getManager(getProject()).createCachedValue(stubProvider, /*trackValue = */false);
} }
@Nullable @Nullable
@@ -272,7 +272,7 @@ public class KotlinLightClassForPackage extends KotlinWrappingLightClass impleme
@NotNull @NotNull
@Override @Override
public PsiClass getDelegate() { public PsiClass getDelegate() {
PsiClass psiClass = LightClassUtil.findClass(packageClassFqName, javaFileStub.getValue().getJavaFileStub()); PsiClass psiClass = LightClassUtil.findClass(packageClassFqName, lightClassDataCache.getValue().getJavaFileStub());
if (psiClass == null) { if (psiClass == null) {
throw new IllegalStateException("Package class was not found " + packageFqName); throw new IllegalStateException("Package class was not found " + packageFqName);
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2013 JetBrains s.r.o. * Copyright 2010-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -22,13 +22,19 @@ import org.jetbrains.jet.lang.psi.JetClassOrObject
trait LightClassData trait LightClassData
trait WithFileStub {
val javaFileStub: PsiJavaFileStub
}
trait LightClassDataForKotlinClass: LightClassData { trait LightClassDataForKotlinClass: LightClassData {
val classOrObject: JetClassOrObject val classOrObject: JetClassOrObject
val descriptor: ClassDescriptor? val descriptor: ClassDescriptor?
val jvmInternalName: String val jvmInternalName: String
} }
object KotlinPackageLightClassData: LightClassData data class KotlinPackageLightClassData(
override val javaFileStub: PsiJavaFileStub
): LightClassData, WithFileStub
data class InnerKotlinClassLightClassData( data class InnerKotlinClassLightClassData(
override val jvmInternalName: String, override val jvmInternalName: String,
@@ -37,13 +43,9 @@ data class InnerKotlinClassLightClassData(
): LightClassDataForKotlinClass ): LightClassDataForKotlinClass
data class OutermostKotlinClassLightClassData( data class OutermostKotlinClassLightClassData(
override val javaFileStub: PsiJavaFileStub,
override val jvmInternalName: String, override val jvmInternalName: String,
override val classOrObject: JetClassOrObject, override val classOrObject: JetClassOrObject,
override val descriptor: ClassDescriptor?, override val descriptor: ClassDescriptor?,
val allInnerClasses: Map<JetClassOrObject, LightClassDataForKotlinClass> val allInnerClasses: Map<JetClassOrObject, InnerKotlinClassLightClassData>
): LightClassDataForKotlinClass ): LightClassDataForKotlinClass, WithFileStub
data class LightClassStubWithData(
val javaFileStub: PsiJavaFileStub,
val classData: LightClassData
)