Refactor PackageCodegen and ClassBuilderOnDemand
Make ClassBuilderOnDemand non-abstract and create its instance directly in PackageCodegen's constructor
This commit is contained in:
@@ -16,49 +16,30 @@
|
||||
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import kotlin.Function0;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.storage.LockBasedStorageManager;
|
||||
import org.jetbrains.jet.storage.NotNullLazyValue;
|
||||
|
||||
import java.util.List;
|
||||
public class ClassBuilderOnDemand {
|
||||
private final NotNullLazyValue<ClassBuilder> classBuilder;
|
||||
|
||||
public abstract class ClassBuilderOnDemand {
|
||||
|
||||
private ClassBuilder classBuilder;
|
||||
|
||||
private final List<ClassBuilderCallback> optionalDeclarations = Lists.newArrayList();
|
||||
|
||||
interface ClassBuilderCallback {
|
||||
void doSomething(@NotNull ClassBuilder classBuilder);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected abstract ClassBuilder createClassBuilder();
|
||||
|
||||
public void addOptionalDeclaration(@NotNull ClassBuilderCallback callback) {
|
||||
optionalDeclarations.add(callback);
|
||||
if (classBuilder != null) {
|
||||
callback.doSomething(classBuilder);
|
||||
}
|
||||
public ClassBuilderOnDemand(@NotNull Function0<ClassBuilder> createClassBuilder) {
|
||||
this.classBuilder = LockBasedStorageManager.NO_LOCKS.createLazyValue(createClassBuilder);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ClassBuilder getClassBuilder() {
|
||||
if (classBuilder == null) {
|
||||
classBuilder = createClassBuilder();
|
||||
for (ClassBuilderCallback callback : optionalDeclarations) {
|
||||
callback.doSomething(classBuilder);
|
||||
}
|
||||
}
|
||||
return classBuilder;
|
||||
return classBuilder.invoke();
|
||||
}
|
||||
|
||||
public void done() {
|
||||
if (classBuilder != null) {
|
||||
classBuilder.done();
|
||||
if (isActivated()) {
|
||||
classBuilder.invoke().done();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isActivated() {
|
||||
return classBuilder != null;
|
||||
return classBuilder.isComputed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,9 +35,6 @@ import org.jetbrains.org.objectweb.asm.Type;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.jet.codegen.AsmUtil.asmTypeByFqNameWithoutInnerClasses;
|
||||
import static org.jetbrains.jet.lang.resolve.java.PackageClassUtils.getPackageClassFqName;
|
||||
|
||||
public class ClassFileFactory implements OutputFileCollection {
|
||||
private final GenerationState state;
|
||||
private final ClassBuilderFactory builderFactory;
|
||||
@@ -57,7 +54,7 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ClassBuilder newVisitor(@NotNull Type asmType, @NotNull Collection<? extends PsiFile> sourceFiles) {
|
||||
public ClassBuilder newVisitor(@NotNull Type asmType, @NotNull Collection<? extends PsiFile> sourceFiles) {
|
||||
String outputFilePath = asmType.getInternalName() + ".class";
|
||||
state.getProgress().reportOutput(toIoFilesIgnoringNonPhysical(sourceFiles), new File(outputFilePath));
|
||||
ClassBuilder answer = builderFactory.newClassBuilder();
|
||||
@@ -106,18 +103,11 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PackageCodegen forPackage(@NotNull final FqName fqName, @NotNull final Collection<JetFile> files) {
|
||||
public PackageCodegen forPackage(@NotNull FqName fqName, @NotNull Collection<JetFile> files) {
|
||||
assert !isDone : "Already done!";
|
||||
PackageCodegen codegen = package2codegen.get(fqName);
|
||||
if (codegen == null) {
|
||||
ClassBuilderOnDemand onDemand = new ClassBuilderOnDemand() {
|
||||
@NotNull
|
||||
@Override
|
||||
protected ClassBuilder createClassBuilder() {
|
||||
return newVisitor(asmTypeByFqNameWithoutInnerClasses(getPackageClassFqName(fqName)), files);
|
||||
}
|
||||
};
|
||||
codegen = new PackageCodegen(onDemand, fqName, state, files);
|
||||
codegen = new PackageCodegen(state, files, fqName);
|
||||
package2codegen.put(fqName, codegen);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,10 +22,10 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import kotlin.Function0;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.context.CodegenContext;
|
||||
@@ -74,28 +74,27 @@ public class PackageCodegen {
|
||||
private final Collection<JetFile> files;
|
||||
private final PackageFragmentDescriptor packageFragment;
|
||||
private final PackageFragmentDescriptor compiledPackageFragment;
|
||||
private final List<DeserializedCallableMemberDescriptor> previouslyCompiledCallables;
|
||||
|
||||
public PackageCodegen(
|
||||
@NotNull ClassBuilderOnDemand v,
|
||||
@NotNull final FqName fqName,
|
||||
@NotNull GenerationState state,
|
||||
@NotNull Collection<JetFile> packageFiles
|
||||
) {
|
||||
public PackageCodegen(@NotNull GenerationState state, @NotNull Collection<JetFile> files, @NotNull final FqName fqName) {
|
||||
this.state = state;
|
||||
this.v = v;
|
||||
this.files = packageFiles;
|
||||
this.files = files;
|
||||
this.packageFragment = getOnlyPackageFragment();
|
||||
this.compiledPackageFragment = getCompiledPackageFragment();
|
||||
this.compiledPackageFragment = getCompiledPackageFragment(packageFragment);
|
||||
this.previouslyCompiledCallables = filterDeserializedCallables(compiledPackageFragment);
|
||||
|
||||
final PsiFile sourceFile = packageFiles.size() == 1 && getPreviouslyCompiledCallables().isEmpty()
|
||||
? packageFiles.iterator().next().getContainingFile() : null;
|
||||
|
||||
v.addOptionalDeclaration(new ClassBuilderOnDemand.ClassBuilderCallback() {
|
||||
this.v = new ClassBuilderOnDemand(new Function0<ClassBuilder>() {
|
||||
@Override
|
||||
public void doSomething(@NotNull ClassBuilder v) {
|
||||
public ClassBuilder invoke() {
|
||||
Collection<JetFile> files = PackageCodegen.this.files;
|
||||
JetFile sourceFile = files.size() == 1 && previouslyCompiledCallables.isEmpty()
|
||||
? files.iterator().next() : null;
|
||||
|
||||
String className = JvmClassName.byFqNameWithoutInnerClasses(getPackageClassFqName(fqName)).getInternalName();
|
||||
ClassBuilder v = PackageCodegen.this.state.getFactory().newVisitor(Type.getObjectType(className), files);
|
||||
v.defineClass(sourceFile, V1_6,
|
||||
ACC_PUBLIC | ACC_FINAL,
|
||||
JvmClassName.byFqNameWithoutInnerClasses(getPackageClassFqName(fqName)).getInternalName(),
|
||||
className,
|
||||
null,
|
||||
"java/lang/Object",
|
||||
ArrayUtil.EMPTY_STRING_ARRAY
|
||||
@@ -104,12 +103,13 @@ public class PackageCodegen {
|
||||
if (sourceFile != null) {
|
||||
v.visitSource(sourceFile.getName(), null);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PackageFragmentDescriptor getCompiledPackageFragment() {
|
||||
private static PackageFragmentDescriptor getCompiledPackageFragment(@NotNull PackageFragmentDescriptor packageFragment) {
|
||||
if (!IncrementalCompilation.ENABLED) {
|
||||
return null;
|
||||
}
|
||||
@@ -125,20 +125,21 @@ public class PackageCodegen {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<DeserializedCallableMemberDescriptor> getPreviouslyCompiledCallables() {
|
||||
private static List<DeserializedCallableMemberDescriptor> filterDeserializedCallables(@Nullable PackageFragmentDescriptor packageFragment) {
|
||||
if (packageFragment == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<DeserializedCallableMemberDescriptor> callables = Lists.newArrayList();
|
||||
if (compiledPackageFragment != null) {
|
||||
for (DeclarationDescriptor member : compiledPackageFragment.getMemberScope().getAllDescriptors()) {
|
||||
if (member instanceof DeserializedCallableMemberDescriptor) {
|
||||
callables.add((DeserializedCallableMemberDescriptor) member);
|
||||
}
|
||||
for (DeclarationDescriptor member : packageFragment.getMemberScope().getAllDescriptors()) {
|
||||
if (member instanceof DeserializedCallableMemberDescriptor) {
|
||||
callables.add((DeserializedCallableMemberDescriptor) member);
|
||||
}
|
||||
}
|
||||
return callables;
|
||||
}
|
||||
|
||||
private void generateDelegationsToPreviouslyCompiled(Map<CallableMemberDescriptor, Runnable> generateCallableMemberTasks) {
|
||||
for (final DeserializedCallableMemberDescriptor member : getPreviouslyCompiledCallables()) {
|
||||
private void generateDelegationsToPreviouslyCompiled(@NotNull Map<CallableMemberDescriptor, Runnable> generateCallableMemberTasks) {
|
||||
for (final DeserializedCallableMemberDescriptor member : previouslyCompiledCallables) {
|
||||
generateCallableMemberTasks.put(member, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
Reference in New Issue
Block a user