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 { public abstract class CodegenContext {
@NotNull
private final DeclarationDescriptor contextType; private final DeclarationDescriptor contextType;
private final OwnerKind contextKind; private final OwnerKind contextKind;
@@ -53,7 +54,7 @@ public abstract class CodegenContext {
protected Type outerWasUsed ; 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.contextType = contextType;
this.contextKind = contextKind; this.contextKind = contextKind;
this.parentContext = parentContext; 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.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor; import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; 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.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor; 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.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.Type;
import org.objectweb.asm.commons.InstructionAdapter; import org.objectweb.asm.commons.InstructionAdapter;
import java.util.List;
/** /**
* @author Stepan Koltsov * @author Stepan Koltsov
*/ */
public class CodegenContexts { 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 @Override
protected ClassDescriptor getThisDescriptor() { protected ClassDescriptor getThisDescriptor() {
return null; return null;
@@ -55,19 +55,21 @@ public class NamespaceCodegen {
} }
public void generate(JetFile file) { 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()) { for (JetDeclaration declaration : file.getDeclarations()) {
if (declaration instanceof JetProperty || declaration instanceof JetNamedFunction) { 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( state.getInjector().getMemberCodegen().generateFunctionOrProperty(
(JetTypeParameterListOwner) declaration, context, v); (JetTypeParameterListOwner) declaration, context, v);
} }
else if (declaration instanceof JetClassOrObject) { 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); state.getInjector().getClassCodegen().generate(context, (JetClassOrObject) declaration);
} }
else if (declaration instanceof JetScript) { else if (declaration instanceof JetScript) {
state.getInjector().getScriptCodegen().generate(context, (JetScript) declaration); state.getInjector().getScriptCodegen().generate((JetScript) declaration);
} }
// else if (declaration instanceof JetFile) { // else if (declaration instanceof JetFile) {
// JetFile childNamespace = (JetFile) declaration; // 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); ScriptDescriptor scriptDescriptor = (ScriptDescriptor) state.getBindingContext().get(BindingContext.SCRIPT, scriptDeclaration);
CodegenContext context = CodegenContexts.STATIC.intoScript(scriptDescriptor);
ClassBuilder classBuilder = classFileFactory.newVisitor("Script.class"); ClassBuilder classBuilder = classFileFactory.newVisitor("Script.class");
classBuilder.defineClass(scriptDeclaration, classBuilder.defineClass(scriptDeclaration,
Opcodes.V1_6, Opcodes.V1_6,
@@ -73,7 +77,7 @@ public class ScriptCodegen {
JdkNames.JL_OBJECT.getInternalName(), JdkNames.JL_OBJECT.getInternalName(),
new String[0]); new String[0]);
genConstructor(scriptDeclaration, scriptDescriptor, classBuilder, outerContext); genConstructor(scriptDeclaration, scriptDescriptor, classBuilder, context);
classBuilder.done(); classBuilder.done();
} }