001    /*
002     * Copyright 2010-2013 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.jet.codegen;
018    
019    import com.intellij.psi.PsiElement;
020    import org.jetbrains.annotations.NotNull;
021    import org.jetbrains.annotations.Nullable;
022    import org.jetbrains.asm4.AnnotationVisitor;
023    import org.jetbrains.asm4.ClassVisitor;
024    import org.jetbrains.asm4.FieldVisitor;
025    import org.jetbrains.asm4.MethodVisitor;
026    
027    public abstract class ClassBuilder {
028        private String thisName;
029    
030        private final MemberMap members = new MemberMap();
031    
032        public static class Concrete extends ClassBuilder {
033            private final ClassVisitor v;
034    
035            public Concrete(@NotNull ClassVisitor v) {
036                this.v = v;
037            }
038    
039            @Override
040            @NotNull
041            public ClassVisitor getVisitor() {
042                return v;
043            }
044        }
045    
046        public FieldVisitor newField(
047                @Nullable PsiElement origin,
048                int access,
049                @NotNull String name,
050                @NotNull String desc,
051                @Nullable String signature,
052                @Nullable Object value
053        ) {
054            return getVisitor().visitField(access, name, desc, signature, value);
055        }
056    
057        public MethodVisitor newMethod(
058                @Nullable PsiElement origin,
059                int access,
060                @NotNull String name,
061                @NotNull String desc,
062                @Nullable String signature,
063                @Nullable String[] exceptions
064        ) {
065            return getVisitor().visitMethod(access, name, desc, signature, exceptions);
066        }
067    
068        @NotNull
069        public MemberMap getMemberMap() {
070            return members;
071        }
072    
073        @NotNull
074        public AnnotationVisitor newAnnotation(@NotNull String desc, boolean visible) {
075            return getVisitor().visitAnnotation(desc, visible);
076        }
077    
078        public void done() {
079            getVisitor().visitEnd();
080        }
081    
082        @NotNull
083        public abstract ClassVisitor getVisitor();
084    
085        public void defineClass(
086                @Nullable PsiElement origin,
087                int version,
088                int access,
089                @NotNull String name,
090                @Nullable String signature,
091                @NotNull String superName,
092                @NotNull String[] interfaces
093        ) {
094            thisName = name;
095            getVisitor().visit(version, access, name, signature, superName, interfaces);
096        }
097    
098        public void visitSource(@NotNull String name, @Nullable String debug) {
099            getVisitor().visitSource(name, debug);
100        }
101    
102        public void visitOuterClass(@NotNull String owner, @Nullable String name, @Nullable String desc) {
103            getVisitor().visitOuterClass(owner, name, desc);
104        }
105    
106        public void visitInnerClass(@NotNull String name, @Nullable String outerName, @Nullable String innerName, int access) {
107            getVisitor().visitInnerClass(name, outerName, innerName, access);
108        }
109    
110        @NotNull
111        public String getThisName() {
112            assert thisName != null : "This name isn't set";
113            return thisName;
114        }
115    }