Fix caching of light class data for nested classes

This commit is contained in:
Alexey Sedunov
2013-12-17 17:03:51 +04:00
parent 09642df623
commit 1d03f9f151
31 changed files with 378 additions and 54 deletions
@@ -1,29 +0,0 @@
/*
* Copyright 2010-2013 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.asJava
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
import org.jetbrains.jet.lang.resolve.BindingContext
import com.intellij.psi.PsiElement
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
data class GeneratedLightClassData(
val javaFileStub: PsiJavaFileStub,
val jvmInternalName: String,
val descriptor: ClassDescriptor?
)
@@ -34,10 +34,10 @@ import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.jet.codegen.CompilationErrorHandler;
import org.jetbrains.jet.codegen.NamespaceCodegen;
import org.jetbrains.jet.codegen.binding.CodegenBinding;
@@ -48,13 +48,15 @@ import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.types.lang.InlineUtil;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
public class KotlinJavaFileStubProvider implements CachedValueProvider<GeneratedLightClassData> {
public class KotlinJavaFileStubProvider implements CachedValueProvider<LightClassStubWithData> {
@NotNull
public static KotlinJavaFileStubProvider createForPackageClass(
@@ -82,8 +84,8 @@ public class KotlinJavaFileStubProvider implements CachedValueProvider<Generated
@NotNull
@Override
public GeneratedLightClassData createStubWithName(PsiJavaFileStub javaFileStub, BindingContext bindingContext) {
return new GeneratedLightClassData(javaFileStub, "", null);
public LightClassStubWithData createLightClassStubWithData(PsiJavaFileStub javaFileStub, BindingContext bindingContext) {
return new LightClassStubWithData(javaFileStub, KotlinPackageLightClassData.instance$);
}
@NotNull
@@ -120,17 +122,32 @@ public class KotlinJavaFileStubProvider implements CachedValueProvider<Generated
@NotNull
@Override
public GeneratedLightClassData createStubWithName(PsiJavaFileStub javaFileStub, BindingContext bindingContext) {
public LightClassStubWithData createLightClassStubWithData(PsiJavaFileStub javaFileStub, BindingContext bindingContext) {
ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, classOrObject);
assert (classDescriptor != null);
Type asmType = bindingContext.get(CodegenBinding.ASM_TYPE, classDescriptor);
assert (asmType != null);
String jvmInternalName = CodegenBinding.getJvmInternalName(bindingContext, classDescriptor);
Collection<ClassDescriptor> allInnerClasses = CodegenBinding.getAllInnerClasses(bindingContext, classDescriptor);
String jvmInternalName = asmType.getClassName();
assert (jvmInternalName != null);
Map<JetClassOrObject, LightClassDataForKotlinClass> innerClassesMap = ContainerUtil.newHashMap();
for (ClassDescriptor innerClassDescriptor : allInnerClasses) {
JetClassOrObject innerClass = (JetClassOrObject) BindingContextUtils.descriptorToDeclaration(
bindingContext, innerClassDescriptor
);
if (innerClass == null) continue;
return new GeneratedLightClassData(javaFileStub, jvmInternalName, classDescriptor);
InnerKotlinClassLightClassData innerLightClassData = new InnerKotlinClassLightClassData(
CodegenBinding.getJvmInternalName(bindingContext, innerClassDescriptor),
innerClass,
innerClassDescriptor
);
innerClassesMap.put(innerClass, innerLightClassData);
}
return new LightClassStubWithData(
javaFileStub,
new OutermostKotlinClassLightClassData(jvmInternalName, classOrObject, classDescriptor, innerClassesMap)
);
}
@NotNull
@@ -173,7 +190,7 @@ public class KotlinJavaFileStubProvider implements CachedValueProvider<Generated
@Nullable
@Override
public Result<GeneratedLightClassData> compute() {
public Result<LightClassStubWithData> compute() {
FqName packageFqName = stubGenerationStrategy.getPackageFqName();
Collection<JetFile> files = stubGenerationStrategy.getFiles();
@@ -221,7 +238,7 @@ public class KotlinJavaFileStubProvider implements CachedValueProvider<Generated
}
return Result.create(
stubGenerationStrategy.createStubWithName(javaFileStub, bindingContext),
stubGenerationStrategy.createLightClassStubWithData(javaFileStub, bindingContext),
local ? PsiModificationTracker.MODIFICATION_COUNT : PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT
);
}
@@ -283,7 +300,7 @@ public class KotlinJavaFileStubProvider implements CachedValueProvider<Generated
private interface StubGenerationStrategy {
@NotNull LightClassConstructionContext createLightClassConstructionContext(@NotNull Collection<JetFile> files);
@NotNull
GeneratedLightClassData createStubWithName(PsiJavaFileStub javaFileStub, BindingContext bindingContext);
LightClassStubWithData createLightClassStubWithData(PsiJavaFileStub javaFileStub, BindingContext bindingContext);
@NotNull Collection<JetFile> getFiles();
@NotNull FqName getPackageFqName();
boolean generateDeclaredClasses();
@@ -42,7 +42,8 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.binding.PsiCodegenPredictor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.ResolvePackage;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.java.jetAsJava.JetJavaMirrorMarker;
import org.jetbrains.jet.lang.resolve.name.FqName;
@@ -59,7 +60,7 @@ import java.util.List;
import static org.jetbrains.jet.lexer.JetTokens.*;
public class KotlinLightClassForExplicitDeclaration extends KotlinWrappingLightClass implements KotlinLightClass, JetJavaMirrorMarker {
private final static Key<CachedValue<GeneratedLightClassData>> JAVA_API_STUB = Key.create("JAVA_API_STUB");
private final static Key<CachedValue<LightClassStubWithData>> JAVA_API_STUB = Key.create("JAVA_API_STUB");
@Nullable
public static KotlinLightClassForExplicitDeclaration create(@NotNull PsiManager manager, @NotNull JetClassOrObject classOrObject) {
@@ -77,7 +78,7 @@ public class KotlinLightClassForExplicitDeclaration extends KotlinWrappingLightC
private static String getJvmInternalName(JetClassOrObject classOrObject) {
if (JetPsiUtil.isLocal(classOrObject)) {
return getGeneratedLightClassData(classOrObject).getJvmInternalName();
return getLightClassDataExactly(classOrObject).getJvmInternalName();
}
return PsiCodegenPredictor.getPredefinedJvmInternalName(classOrObject);
}
@@ -156,24 +157,21 @@ public class KotlinLightClassForExplicitDeclaration extends KotlinWrappingLightC
@NotNull
private PsiJavaFileStub getJavaFileStub() {
return getGeneratedLightClassData().getJavaFileStub();
return getLightClassStubWithData().getJavaFileStub();
}
@NotNull
private ClassDescriptor getDescriptor() {
ClassDescriptor descriptor = getGeneratedLightClassData().getDescriptor();
assert descriptor != null;
return descriptor;
return getLightClassDataExactly(classOrObject).getDescriptor();
}
@NotNull
private GeneratedLightClassData getGeneratedLightClassData() {
return getGeneratedLightClassData(classOrObject);
private LightClassStubWithData getLightClassStubWithData() {
return getLightClassStubWithData(classOrObject);
}
@NotNull
private static GeneratedLightClassData getGeneratedLightClassData(JetClassOrObject classOrObject) {
private static LightClassStubWithData getLightClassStubWithData(JetClassOrObject classOrObject) {
JetClassOrObject outermostClassOrObject = getOutermostClassOrObject(classOrObject);
return CachedValuesManager.getManager(classOrObject.getProject()).getCachedValue(
outermostClassOrObject,
@@ -183,6 +181,18 @@ public class KotlinLightClassForExplicitDeclaration extends KotlinWrappingLightC
);
}
@NotNull
private static LightClassDataForKotlinClass getLightClassDataExactly(JetClassOrObject classOrObject) {
OutermostKotlinClassLightClassData data =
(OutermostKotlinClassLightClassData) getLightClassStubWithData(classOrObject).getClassData();
if (data.getClassOrObject().equals(classOrObject)) return data;
LightClassDataForKotlinClass innerClassData = data.getAllInnerClasses().get(classOrObject);
assert innerClassData != null;
return innerClassData;
}
@NotNull
private static JetClassOrObject getOutermostClassOrObject(@NotNull JetClassOrObject classOrObject) {
JetClassOrObject outermostClass = JetPsiUtil.getOutermostClassOrObject(classOrObject);
@@ -47,7 +47,7 @@ public class KotlinLightClassForPackage extends KotlinWrappingLightClass impleme
private final GlobalSearchScope searchScope;
private final Collection<JetFile> files;
private final int hashCode;
private final CachedValue<GeneratedLightClassData> javaFileStub;
private final CachedValue<LightClassStubWithData> javaFileStub;
private final PsiModifierList modifierList;
private final LightEmptyImplementsList implementsList;
@@ -0,0 +1,52 @@
/*
* Copyright 2010-2013 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.asJava
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
import org.jetbrains.jet.lang.psi.JetClassOrObject
trait LightClassData {
val jvmInternalName: String
}
trait LightClassDataForKotlinClass: LightClassData {
val classOrObject: JetClassOrObject
val descriptor: ClassDescriptor
}
object KotlinPackageLightClassData: LightClassData {
override val jvmInternalName: String = ""
}
data class InnerKotlinClassLightClassData(
override val jvmInternalName: String,
override val classOrObject: JetClassOrObject,
override val descriptor: ClassDescriptor
): LightClassDataForKotlinClass
data class OutermostKotlinClassLightClassData(
override val jvmInternalName: String,
override val classOrObject: JetClassOrObject,
override val descriptor: ClassDescriptor,
val allInnerClasses: Map<JetClassOrObject, LightClassDataForKotlinClass>
): LightClassDataForKotlinClass
data class LightClassStubWithData(
val javaFileStub: PsiJavaFileStub,
val classData: LightClassData
)