safer CodegenContext: require contextType to be not null

This commit is contained in:
Stepan Koltsov
2012-06-02 02:18:29 +04:00
parent 2d4ad5e408
commit a5eaa3abe3
4 changed files with 58 additions and 7 deletions
@@ -37,6 +37,7 @@ import java.util.LinkedHashMap;
*/
public abstract class CodegenContext {
@NotNull
private final DeclarationDescriptor contextType;
private final OwnerKind contextKind;
@@ -53,7 +54,7 @@ public abstract class CodegenContext {
protected Type outerWasUsed ;
public CodegenContext(DeclarationDescriptor contextType, OwnerKind contextKind, @Nullable CodegenContext parentContext, @Nullable ObjectOrClosureCodegen closureCodegen) {
public CodegenContext(@NotNull DeclarationDescriptor contextType, OwnerKind contextKind, @Nullable CodegenContext parentContext, @Nullable ObjectOrClosureCodegen closureCodegen) {
this.contextType = contextType;
this.contextKind = contextKind;
this.parentContext = parentContext;
@@ -22,18 +22,62 @@ import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorVisitor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import java.util.List;
/**
* @author Stepan Koltsov
*/
public class CodegenContexts {
public static final CodegenContext STATIC = new CodegenContext(null, OwnerKind.NAMESPACE, null, null) {
private static class FakeDescriptorForStaticContext implements DeclarationDescriptor {
@NotNull
@Override
public DeclarationDescriptor getOriginal() {
throw new IllegalStateException();
}
@Override
public DeclarationDescriptor getContainingDeclaration() {
throw new IllegalStateException();
}
@Override
public DeclarationDescriptor substitute(TypeSubstitutor substitutor) {
throw new IllegalStateException();
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
throw new IllegalStateException();
}
@Override
public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
throw new IllegalStateException();
}
@Override
public List<AnnotationDescriptor> getAnnotations() {
throw new IllegalStateException();
}
@NotNull @Override public Name getName() {
return null;
}
}
public static final CodegenContext STATIC = new CodegenContext(new FakeDescriptorForStaticContext(), OwnerKind.NAMESPACE, null, null) {
@Override
protected ClassDescriptor getThisDescriptor() {
return null;
@@ -55,19 +55,21 @@ public class NamespaceCodegen {
}
public void generate(JetFile file) {
NamespaceDescriptor descriptor = state.getBindingContext().get(BindingContext.FILE_TO_NAMESPACE, file);
final CodegenContext context = CodegenContexts.STATIC.intoNamespace(descriptor);
for (JetDeclaration declaration : file.getDeclarations()) {
if (declaration instanceof JetProperty || declaration instanceof JetNamedFunction) {
NamespaceDescriptor descriptor = state.getBindingContext().get(BindingContext.FILE_TO_NAMESPACE, file);
final CodegenContext context = CodegenContexts.STATIC.intoNamespace(descriptor);
state.getInjector().getMemberCodegen().generateFunctionOrProperty(
(JetTypeParameterListOwner) declaration, context, v);
}
else if (declaration instanceof JetClassOrObject) {
NamespaceDescriptor descriptor = state.getBindingContext().get(BindingContext.FILE_TO_NAMESPACE, file);
final CodegenContext context = CodegenContexts.STATIC.intoNamespace(descriptor);
state.getInjector().getClassCodegen().generate(context, (JetClassOrObject) declaration);
}
else if (declaration instanceof JetScript) {
state.getInjector().getScriptCodegen().generate(context, (JetScript) declaration);
state.getInjector().getScriptCodegen().generate((JetScript) declaration);
}
// else if (declaration instanceof JetFile) {
// JetFile childNamespace = (JetFile) declaration;
@@ -62,8 +62,12 @@ public class ScriptCodegen {
public void generate(CodegenContext outerContext, JetScript scriptDeclaration) {
public void generate(JetScript scriptDeclaration) {
ScriptDescriptor scriptDescriptor = (ScriptDescriptor) state.getBindingContext().get(BindingContext.SCRIPT, scriptDeclaration);
CodegenContext context = CodegenContexts.STATIC.intoScript(scriptDescriptor);
ClassBuilder classBuilder = classFileFactory.newVisitor("Script.class");
classBuilder.defineClass(scriptDeclaration,
Opcodes.V1_6,
@@ -73,7 +77,7 @@ public class ScriptCodegen {
JdkNames.JL_OBJECT.getInternalName(),
new String[0]);
genConstructor(scriptDeclaration, scriptDescriptor, classBuilder, outerContext);
genConstructor(scriptDeclaration, scriptDescriptor, classBuilder, context);
classBuilder.done();
}