001    /*
002     * Copyright 2010-2015 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.kotlin.codegen;
018    
019    import com.intellij.psi.PsiElement;
020    import org.jetbrains.annotations.NotNull;
021    import org.jetbrains.annotations.Nullable;
022    import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
023    import org.jetbrains.org.objectweb.asm.*;
024    
025    public abstract class AbstractClassBuilder implements ClassBuilder {
026        protected static final MethodVisitor EMPTY_METHOD_VISITOR = new MethodVisitor(Opcodes.ASM5) {};
027        protected static final FieldVisitor EMPTY_FIELD_VISITOR = new FieldVisitor(Opcodes.ASM5) {};
028    
029        private String thisName;
030    
031        private final JvmSerializationBindings serializationBindings = new JvmSerializationBindings();
032    
033        public static class Concrete extends AbstractClassBuilder {
034            private final ClassVisitor v;
035    
036            public Concrete(@NotNull ClassVisitor v) {
037                this.v = v;
038            }
039    
040            @Override
041            @NotNull
042            public ClassVisitor getVisitor() {
043                return v;
044            }
045        }
046    
047        @Override
048        @NotNull
049        public FieldVisitor newField(
050                @NotNull JvmDeclarationOrigin origin,
051                int access,
052                @NotNull String name,
053                @NotNull String desc,
054                @Nullable String signature,
055                @Nullable Object value
056        ) {
057            FieldVisitor visitor = getVisitor().visitField(access, name, desc, signature, value);
058            if (visitor == null) {
059                return EMPTY_FIELD_VISITOR;
060            }
061            return visitor;
062        }
063    
064        @Override
065        @NotNull
066        public MethodVisitor newMethod(
067                @NotNull JvmDeclarationOrigin origin,
068                int access,
069                @NotNull String name,
070                @NotNull String desc,
071                @Nullable String signature,
072                @Nullable String[] exceptions
073        ) {
074            MethodVisitor visitor = getVisitor().visitMethod(access, name, desc, signature, exceptions);
075            if (visitor == null) {
076                return EMPTY_METHOD_VISITOR;
077            }
078            return visitor;
079        }
080    
081        @Override
082        @NotNull
083        public JvmSerializationBindings getSerializationBindings() {
084            return serializationBindings;
085        }
086    
087        @Override
088        @NotNull
089        public AnnotationVisitor newAnnotation(@NotNull String desc, boolean visible) {
090            return getVisitor().visitAnnotation(desc, visible);
091        }
092    
093        @Override
094        public void done() {
095            getVisitor().visitEnd();
096        }
097    
098        @Override
099        public void defineClass(
100                @Nullable PsiElement origin,
101                int version,
102                int access,
103                @NotNull String name,
104                @Nullable String signature,
105                @NotNull String superName,
106                @NotNull String[] interfaces
107        ) {
108            thisName = name;
109            getVisitor().visit(version, access, name, signature, superName, interfaces);
110        }
111    
112        @Override
113        public void visitSource(@NotNull String name, @Nullable String debug) {
114            getVisitor().visitSource(name, debug);
115        }
116    
117        @Override
118        public void visitOuterClass(@NotNull String owner, @Nullable String name, @Nullable String desc) {
119            getVisitor().visitOuterClass(owner, name, desc);
120        }
121    
122        @Override
123        public void visitInnerClass(@NotNull String name, @Nullable String outerName, @Nullable String innerName, int access) {
124            getVisitor().visitInnerClass(name, outerName, innerName, access);
125        }
126    
127        @Override
128        @NotNull
129        public String getThisName() {
130            assert thisName != null : "This name isn't set";
131            return thisName;
132        }
133    }