Make CodegenBinding.ASM_TYPE a collective slice

Change Type->JetFile mapping logic in PsiCodegenPredictor to be less hackish,
but probably the compiler will start requiring a little more memory due to a
collective slice multimap
This commit is contained in:
Alexander Udalov
2014-05-06 16:37:07 +04:00
parent d737932bc7
commit 3ac89030c7
3 changed files with 21 additions and 25 deletions
@@ -50,7 +50,7 @@ public class CodegenBinding {
public static final WritableSlice<ScriptDescriptor, ClassDescriptor> CLASS_FOR_SCRIPT = Slices.createSimpleSlice();
public static final WritableSlice<ClassDescriptor, Type> ASM_TYPE = Slices.createSimpleSlice();
public static final WritableSlice<ClassDescriptor, Type> ASM_TYPE = Slices.createCollectiveSlice();
public static final WritableSlice<ClassDescriptor, Boolean> ENUM_ENTRY_CLASS_NEED_SUBCLASS = Slices.createSimpleSetSlice();
@@ -65,9 +65,9 @@ public class CodegenBinding {
private CodegenBinding() {
}
public static void initTrace(BindingTrace bindingTrace, Collection<JetFile> files, GenerationState.GenerateClassFilter filter) {
CodegenAnnotatingVisitor visitor = new CodegenAnnotatingVisitor(bindingTrace, filter);
for (JetFile file : allFilesInPackages(bindingTrace.getBindingContext(), files)) {
public static void initTrace(@NotNull GenerationState state) {
CodegenAnnotatingVisitor visitor = new CodegenAnnotatingVisitor(state.getBindingTrace(), state.getGenerateDeclaredClassFilter());
for (JetFile file : allFilesInPackages(state.getBindingContext(), state.getFiles())) {
file.accept(visitor);
}
}
@@ -16,26 +16,27 @@
package org.jetbrains.jet.codegen.binding;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.ClassBuilderFactories;
import org.jetbrains.jet.codegen.PackageCodegen;
import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.util.slicedmap.WritableSlice;
import org.jetbrains.org.objectweb.asm.Type;
import java.util.ArrayList;
import java.util.Collection;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration;
@@ -145,25 +146,21 @@ public final class PsiCodegenPredictor {
public static JetFile getFileForCodegenNamedClass(
@NotNull BindingContext context,
@NotNull Collection<JetFile> allPackageFiles,
@NotNull final String classInternalName
@NotNull String classInternalName
) {
final Ref<DeclarationDescriptor> resultingDescriptor = Ref.create();
Project project = allPackageFiles.iterator().next().getProject();
GenerationState state =
new GenerationState(project, ClassBuilderFactories.THROW_EXCEPTION, context, new ArrayList<JetFile>(allPackageFiles));
state.beforeCompile();
DelegatingBindingTrace trace = new DelegatingBindingTrace(context, "trace in PsiCodegenPredictor") {
@Override
public <K, V> void record(WritableSlice<K, V> slice, K key, V value) {
super.record(slice, key, value);
if (slice == CodegenBinding.ASM_TYPE && key instanceof DeclarationDescriptor && value instanceof Type) {
if (classInternalName.equals(((Type) value).getInternalName())) {
resultingDescriptor.set((DeclarationDescriptor) key);
}
}
BindingTrace trace = state.getBindingTrace();
for (ClassDescriptor classDescriptor : trace.getKeys(CodegenBinding.ASM_TYPE)) {
Type type = trace.get(CodegenBinding.ASM_TYPE, classDescriptor);
if (type != null && classInternalName.equals(type.getInternalName())) {
return BindingContextUtils.getContainingFile(trace.getBindingContext(), classDescriptor);
}
};
}
CodegenBinding.initTrace(trace, allPackageFiles, GenerationState.GenerateClassFilter.GENERATE_ALL);
return resultingDescriptor.isNull() ? null
: BindingContextUtils.getContainingFile(trace.getBindingContext(), resultingDescriptor.get());
return null;
}
}
@@ -207,8 +207,7 @@ public class GenerationState {
public void beforeCompile() {
markUsed();
//noinspection unchecked
CodegenBinding.initTrace(getBindingTrace(), getFiles(), getGenerateDeclaredClassFilter());
CodegenBinding.initTrace(this);
}
private void markUsed() {