Extracting class builder interface

This commit is contained in:
Mikhael Bogdanov
2014-02-14 14:13:51 +04:00
parent 9028e24d35
commit e695f0a516
4 changed files with 156 additions and 72 deletions
@@ -0,0 +1,132 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.codegen;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.*;
public abstract class AbstractClassBuilder implements ClassBuilder {
protected static final MethodVisitor EMPTY_METHOD_VISITOR = new MethodVisitor(Opcodes.ASM4) {};
protected static final FieldVisitor EMPTY_FIELD_VISITOR = new FieldVisitor(Opcodes.ASM4) {};
private String thisName;
private final JvmSerializationBindings serializationBindings = new JvmSerializationBindings();
public static class Concrete extends AbstractClassBuilder {
private final ClassVisitor v;
public Concrete(@NotNull ClassVisitor v) {
this.v = v;
}
@Override
@NotNull
public ClassVisitor getVisitor() {
return v;
}
}
@Override
@NotNull
public FieldVisitor newField(
@Nullable PsiElement origin,
int access,
@NotNull String name,
@NotNull String desc,
@Nullable String signature,
@Nullable Object value
) {
FieldVisitor visitor = getVisitor().visitField(access, name, desc, signature, value);
if (visitor == null) {
return EMPTY_FIELD_VISITOR;
}
return visitor;
}
@Override
@NotNull
public MethodVisitor newMethod(
@Nullable PsiElement origin,
int access,
@NotNull String name,
@NotNull String desc,
@Nullable String signature,
@Nullable String[] exceptions
) {
MethodVisitor visitor = getVisitor().visitMethod(access, name, desc, signature, exceptions);
if (visitor == null) {
return EMPTY_METHOD_VISITOR;
}
return visitor;
}
@Override
@NotNull
public JvmSerializationBindings getSerializationBindings() {
return serializationBindings;
}
@Override
@NotNull
public AnnotationVisitor newAnnotation(@NotNull String desc, boolean visible) {
return getVisitor().visitAnnotation(desc, visible);
}
@Override
public void done() {
getVisitor().visitEnd();
}
@Override
public void defineClass(
@Nullable PsiElement origin,
int version,
int access,
@NotNull String name,
@Nullable String signature,
@NotNull String superName,
@NotNull String[] interfaces
) {
thisName = name;
getVisitor().visit(version, access, name, signature, superName, interfaces);
}
@Override
public void visitSource(@NotNull String name, @Nullable String debug) {
getVisitor().visitSource(name, debug);
}
@Override
public void visitOuterClass(@NotNull String owner, @Nullable String name, @Nullable String desc) {
getVisitor().visitOuterClass(owner, name, desc);
}
@Override
public void visitInnerClass(@NotNull String name, @Nullable String outerName, @Nullable String innerName, int access) {
getVisitor().visitInnerClass(name, outerName, innerName, access);
}
@Override
@NotNull
public String getThisName() {
assert thisName != null : "This name isn't set";
return thisName;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,80 +19,44 @@ package org.jetbrains.jet.codegen;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.*;
public abstract class ClassBuilder {
protected static final MethodVisitor EMPTY_METHOD_VISITOR = new MethodVisitor(Opcodes.ASM4) {};
protected static final FieldVisitor EMPTY_FIELD_VISITOR = new FieldVisitor(Opcodes.ASM4) {};
private String thisName;
private final JvmSerializationBindings serializationBindings = new JvmSerializationBindings();
public static class Concrete extends ClassBuilder {
private final ClassVisitor v;
public Concrete(@NotNull ClassVisitor v) {
this.v = v;
}
@Override
@NotNull
public ClassVisitor getVisitor() {
return v;
}
}
import org.jetbrains.asm4.AnnotationVisitor;
import org.jetbrains.asm4.ClassVisitor;
import org.jetbrains.asm4.FieldVisitor;
import org.jetbrains.asm4.MethodVisitor;
public interface ClassBuilder {
@NotNull
public FieldVisitor newField(
FieldVisitor newField(
@Nullable PsiElement origin,
int access,
@NotNull String name,
@NotNull String desc,
@Nullable String signature,
@Nullable Object value
) {
FieldVisitor visitor = getVisitor().visitField(access, name, desc, signature, value);
if (visitor == null) {
return EMPTY_FIELD_VISITOR;
}
return visitor;
}
);
@NotNull
public MethodVisitor newMethod(
MethodVisitor newMethod(
@Nullable PsiElement origin,
int access,
@NotNull String name,
@NotNull String desc,
@Nullable String signature,
@Nullable String[] exceptions
) {
MethodVisitor visitor = getVisitor().visitMethod(access, name, desc, signature, exceptions);
if (visitor == null) {
return EMPTY_METHOD_VISITOR;
}
return visitor;
}
);
@NotNull
public JvmSerializationBindings getSerializationBindings() {
return serializationBindings;
}
JvmSerializationBindings getSerializationBindings();
@NotNull
public AnnotationVisitor newAnnotation(@NotNull String desc, boolean visible) {
return getVisitor().visitAnnotation(desc, visible);
}
AnnotationVisitor newAnnotation(@NotNull String desc, boolean visible);
public void done() {
getVisitor().visitEnd();
}
void done();
@NotNull
public abstract ClassVisitor getVisitor();
ClassVisitor getVisitor();
public void defineClass(
void defineClass(
@Nullable PsiElement origin,
int version,
int access,
@@ -100,26 +64,14 @@ public abstract class ClassBuilder {
@Nullable String signature,
@NotNull String superName,
@NotNull String[] interfaces
) {
thisName = name;
getVisitor().visit(version, access, name, signature, superName, interfaces);
}
);
public void visitSource(@NotNull String name, @Nullable String debug) {
getVisitor().visitSource(name, debug);
}
void visitSource(@NotNull String name, @Nullable String debug);
public void visitOuterClass(@NotNull String owner, @Nullable String name, @Nullable String desc) {
getVisitor().visitOuterClass(owner, name, desc);
}
void visitOuterClass(@NotNull String owner, @Nullable String name, @Nullable String desc);
public void visitInnerClass(@NotNull String name, @Nullable String outerName, @Nullable String innerName, int access) {
getVisitor().visitInnerClass(name, outerName, innerName, access);
}
void visitInnerClass(@NotNull String name, @Nullable String outerName, @Nullable String innerName, int access);
@NotNull
public String getThisName() {
assert thisName != null : "This name isn't set";
return thisName;
}
String getThisName();
}
@@ -63,7 +63,7 @@ public class ClassBuilderFactories {
@Override
public ClassBuilder newClassBuilder() {
return new ClassBuilder.Concrete(new BinaryClassWriter());
return new AbstractClassBuilder.Concrete(new BinaryClassWriter());
}
@Override
@@ -98,7 +98,7 @@ public class ClassBuilderFactories {
}
}
private static class TraceBuilder extends ClassBuilder.Concrete {
private static class TraceBuilder extends AbstractClassBuilder.Concrete {
public final BinaryClassWriter binary;
public TraceBuilder(BinaryClassWriter binary) {
@@ -28,7 +28,7 @@ import org.jetbrains.asm4.ClassReader;
import org.jetbrains.asm4.ClassVisitor;
import org.jetbrains.asm4.FieldVisitor;
import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.jet.codegen.ClassBuilder;
import org.jetbrains.jet.codegen.AbstractClassBuilder;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
@@ -36,7 +36,7 @@ import org.jetbrains.jet.lang.resolve.name.FqName;
import java.util.List;
public class StubClassBuilder extends ClassBuilder {
public class StubClassBuilder extends AbstractClassBuilder {
private static final InnerClassSourceStrategy<Object> EMPTY_STRATEGY = new InnerClassSourceStrategy<Object>() {
@Override
public Object findInnerClass(String s, Object o) {