Recording psi element and descriptor for which a class is being emitted

This commit is contained in:
Andrey Breslav
2014-05-22 12:16:06 +04:00
parent af2cd46327
commit 8135391ba4
11 changed files with 46 additions and 21 deletions
@@ -16,7 +16,9 @@
package org.jetbrains.jet.codegen;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.org.objectweb.asm.ClassWriter;
import org.jetbrains.org.objectweb.asm.util.TraceClassVisitor;
@@ -33,8 +35,9 @@ public class ClassBuilderFactories {
return ClassBuilderMode.FULL;
}
@NotNull
@Override
public ClassBuilder newClassBuilder() {
public ClassBuilder newClassBuilder(PsiElement forElement, DeclarationDescriptor forDescriptor) {
throw new IllegalStateException();
}
@@ -57,8 +60,9 @@ public class ClassBuilderFactories {
return ClassBuilderMode.FULL;
}
@NotNull
@Override
public ClassBuilder newClassBuilder() {
public ClassBuilder newClassBuilder(PsiElement forElement, DeclarationDescriptor forDescriptor) {
return new TraceBuilder(new BinaryClassWriter());
}
@@ -86,8 +90,9 @@ public class ClassBuilderFactories {
return ClassBuilderMode.FULL;
}
@NotNull
@Override
public ClassBuilder newClassBuilder() {
public ClassBuilder newClassBuilder(PsiElement forElement, DeclarationDescriptor forDescriptor) {
return new AbstractClassBuilder.Concrete(new BinaryClassWriter());
}
@@ -16,13 +16,17 @@
package org.jetbrains.jet.codegen;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
public interface ClassBuilderFactory {
@NotNull
ClassBuilderMode getClassBuilderMode();
ClassBuilder newClassBuilder();
@NotNull
ClassBuilder newClassBuilder(@Nullable PsiElement forElement, @Nullable DeclarationDescriptor forDescriptor);
String asText(ClassBuilder builder);
@@ -18,6 +18,7 @@ package org.jetbrains.jet.codegen;
import com.google.common.collect.Lists;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
@@ -27,6 +28,7 @@ import org.jetbrains.annotations.TestOnly;
import org.jetbrains.jet.OutputFile;
import org.jetbrains.jet.OutputFileCollection;
import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.org.objectweb.asm.Type;
@@ -48,16 +50,24 @@ public class ClassFileFactory implements OutputFileCollection {
}
@NotNull
public ClassBuilder newVisitor(@NotNull Type asmType, @NotNull PsiFile sourceFile) {
return newVisitor(asmType, Collections.singletonList(sourceFile));
public ClassBuilder newVisitor(
@Nullable PsiElement forElement,
@Nullable DeclarationDescriptor forDescriptor,
@NotNull Type asmType,
@NotNull PsiFile sourceFile) {
return newVisitor(forElement == null ? sourceFile : forElement, forDescriptor, asmType, Collections.singletonList(sourceFile));
}
@NotNull
public ClassBuilder newVisitor(@NotNull Type asmType, @NotNull Collection<? extends PsiFile> sourceFiles) {
public ClassBuilder newVisitor(
@Nullable PsiElement forElement,
@Nullable DeclarationDescriptor forDescriptor,
@NotNull Type asmType,
@NotNull Collection<? extends PsiFile> sourceFiles) {
String outputFilePath = asmType.getInternalName() + ".class";
List<File> ioSourceFiles = toIoFilesIgnoringNonPhysical(sourceFiles);
state.getProgress().reportOutput(ioSourceFiles, new File(outputFilePath));
ClassBuilder answer = builderFactory.newClassBuilder();
ClassBuilder answer = builderFactory.newClassBuilder(forElement, forDescriptor);
generators.put(outputFilePath, new ClassBuilderAndSourceFileList(answer, ioSourceFiles));
return answer;
}
@@ -119,7 +119,7 @@ public class ClosureCodegen extends ParentCodegenAware {
}
public void gen() {
ClassBuilder cv = state.getFactory().newVisitor(asmType, fun.getContainingFile());
ClassBuilder cv = state.getFactory().newVisitor(fun, funDescriptor, asmType, fun.getContainingFile());
FunctionDescriptor erasedInterfaceFunction;
if (samType == null) {
@@ -171,12 +171,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
public CalculatedClosure generateObjectLiteral(@NotNull JetObjectLiteralExpression literal) {
JetObjectDeclaration objectDeclaration = literal.getObjectDeclaration();
Type asmType = asmTypeForAnonymousClass(bindingContext, objectDeclaration);
ClassBuilder classBuilder = state.getFactory().newVisitor(asmType, literal.getContainingFile());
ClassDescriptor classDescriptor = bindingContext.get(CLASS, objectDeclaration);
assert classDescriptor != null;
Type asmType = asmTypeForAnonymousClass(bindingContext, objectDeclaration);
ClassBuilder classBuilder = state.getFactory().newVisitor(objectDeclaration, classDescriptor, asmType, literal.getContainingFile());
ClassContext objectContext = context.intoAnonymousClass(classDescriptor, this);
new ImplementationBodyCodegen(objectDeclaration, objectContext, classBuilder, state, getParentCodegen()).generate();
@@ -263,7 +264,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
assert descriptor != null;
Type asmType = asmTypeForAnonymousClass(bindingContext, declaration);
ClassBuilder classBuilder = state.getFactory().newVisitor(asmType, declaration.getContainingFile());
ClassBuilder classBuilder = state.getFactory().newVisitor(declaration, descriptor, asmType, declaration.getContainingFile());
ClassContext objectContext = context.intoAnonymousClass(descriptor, this);
new ImplementationBodyCodegen(declaration, objectContext, classBuilder, state, getParentCodegen()).generate();
@@ -162,13 +162,13 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
}
Type classType = state.getTypeMapper().mapClass(descriptor);
ClassBuilder classBuilder = state.getFactory().newVisitor(classType, aClass.getContainingFile());
ClassBuilder classBuilder = state.getFactory().newVisitor(aClass, descriptor, classType, aClass.getContainingFile());
ClassContext classContext = parentContext.intoClass(descriptor, OwnerKind.IMPLEMENTATION, state);
new ImplementationBodyCodegen(aClass, classContext, classBuilder, state, parentCodegen).generate();
if (aClass instanceof JetClass && ((JetClass) aClass).isTrait()) {
Type traitImplType = state.getTypeMapper().mapTraitImpl(descriptor);
ClassBuilder traitImplBuilder = state.getFactory().newVisitor(traitImplType, aClass.getContainingFile());
ClassBuilder traitImplBuilder = state.getFactory().newVisitor(aClass, descriptor, traitImplType, aClass.getContainingFile());
ClassContext traitImplContext = parentContext.intoClass(descriptor, OwnerKind.TRAIT_IMPL, state);
new TraitImplBodyCodegen(aClass, traitImplContext, traitImplBuilder, state, parentCodegen).generate();
}
@@ -89,7 +89,9 @@ public class PackageCodegen {
String className = AsmUtil.internalNameByFqNameWithoutInnerClasses(getPackageClassFqName(fqName));
ClassBuilder v = PackageCodegen.this.state.getFactory()
.newVisitor(Type.getObjectType(className), PackagePartClassUtils.getPackageFilesWithCallables(files));
.newVisitor(
null, packageFragment,
Type.getObjectType(className), PackagePartClassUtils.getPackageFilesWithCallables(files));
v.defineClass(sourceFile, V1_6,
ACC_PUBLIC | ACC_FINAL,
className,
@@ -279,7 +281,7 @@ public class PackageCodegen {
if (!generatePackagePart) return null;
ClassBuilder builder = state.getFactory().newVisitor(packagePartType, file);
ClassBuilder builder = state.getFactory().newVisitor(file, packageFragment, packagePartType, file);
new PackagePartCodegen(builder, file, packagePartType, packagePartContext, state).generate();
@@ -62,7 +62,7 @@ public class SamWrapperCodegen {
// e.g. compare(T, T)
SimpleFunctionDescriptor erasedInterfaceFunction = samType.getAbstractMethod().getOriginal();
ClassBuilder cv = state.getFactory().newVisitor(asmType, file);
ClassBuilder cv = state.getFactory().newVisitor(null, erasedInterfaceFunction, asmType, file);
cv.defineClass(file,
V1_6,
ACC_FINAL,
@@ -58,7 +58,7 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
Type className = state.getBindingContext().get(ASM_TYPE, classDescriptorForScript);
assert className != null;
ClassBuilder builder = state.getFactory().newVisitor(className, declaration.getContainingFile());
ClassBuilder builder = state.getFactory().newVisitor(declaration, classDescriptorForScript, className, declaration.getContainingFile());
List<ScriptDescriptor> earlierScripts = state.getEarlierScriptsForReplInterpreter();
ScriptContext scriptContext = parentContext.intoScript(
scriptDescriptor,
@@ -297,7 +297,7 @@ public class AnonymousObjectTransformer {
@NotNull
private ClassBuilder createClassBuilder() {
ClassBuilder classBuilder = state.getFactory().newVisitor(newLambdaType, inliningContext.getRoot().callElement.getContainingFile());
ClassBuilder classBuilder = state.getFactory().newVisitor(null, null, newLambdaType, inliningContext.getRoot().callElement.getContainingFile());
return new RemappingClassBuilder(classBuilder, new TypeRemapper(inliningContext.typeMapping));
}
@@ -16,12 +16,14 @@
package org.jetbrains.jet.asJava;
import com.intellij.psi.PsiElement;
import com.intellij.psi.stubs.StubElement;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.codegen.ClassBuilder;
import org.jetbrains.jet.codegen.ClassBuilderFactory;
import org.jetbrains.jet.codegen.ClassBuilderMode;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
/*package*/ class KotlinLightClassBuilderFactory implements ClassBuilderFactory {
private final Stack<StubElement> stubStack;
@@ -36,8 +38,9 @@ import org.jetbrains.jet.codegen.ClassBuilderMode;
return ClassBuilderMode.LIGHT_CLASSES;
}
@NotNull
@Override
public ClassBuilder newClassBuilder() {
public ClassBuilder newClassBuilder(PsiElement forElement, DeclarationDescriptor forDescriptor) {
return new StubClassBuilder(stubStack);
}