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.inline;
018    
019    import org.jetbrains.asm4.AnnotationVisitor;
020    import org.jetbrains.asm4.Label;
021    import org.jetbrains.asm4.MethodVisitor;
022    import org.jetbrains.asm4.Opcodes;
023    import org.jetbrains.asm4.commons.InstructionAdapter;
024    import org.jetbrains.asm4.tree.FieldInsnNode;
025    import org.jetbrains.jet.codegen.StackValue;
026    
027    public class RemapVisitor extends InstructionAdapter {
028    
029        private final Label end;
030    
031        private final VarRemapper remapper;
032    
033        private final boolean remapReturn;
034        private FieldRemapper nodeRemapper;
035    
036        protected RemapVisitor(MethodVisitor mv, Label end, VarRemapper.ParamRemapper remapper, boolean remapReturn, FieldRemapper nodeRemapper) {
037            super(InlineCodegenUtil.API, mv);
038            this.end = end;
039            this.remapper = remapper;
040            this.remapReturn = remapReturn;
041            this.nodeRemapper = nodeRemapper;
042        }
043    
044        @Override
045        public void visitInsn(int opcode) {
046            if (remapReturn && opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) {
047                super.visitJumpInsn(Opcodes.GOTO, end);
048            }
049            else {
050                super.visitInsn(opcode);
051            }
052        }
053    
054        @Override
055        public void visitIincInsn(int var, int increment) {
056            remapper.visitIincInsn(var, increment, mv);
057        }
058    
059        @Override
060        public void visitVarInsn(int opcode, int var) {
061            remapper.visitVarInsn(opcode, var, new InstructionAdapter(mv));
062        }
063    
064        @Override
065        public void visitFieldInsn(int opcode, String owner, String name, String desc) {
066            if (name.startsWith("$$$")) {
067                if (nodeRemapper instanceof RegeneratedLambdaFieldRemapper || nodeRemapper.isRoot()) {
068                    FieldInsnNode fin = new FieldInsnNode(opcode, owner, name, desc);
069                    StackValue inline = nodeRemapper.getFieldForInline(fin, null);
070                    assert inline != null : "Captured field should have not null stackValue " + fin;
071                    inline.put(inline.type, this);
072                }
073                else {
074                    super.visitFieldInsn(opcode, owner, name, desc);
075                }
076            }
077            else {
078                super.visitFieldInsn(opcode, owner, name, desc);
079            }
080        }
081    
082        @Override
083        public void visitLocalVariable(
084                String name, String desc, String signature, Label start, Label end, int index
085        ) {
086    
087        }
088    
089        @Override
090        public AnnotationVisitor visitAnnotationDefault() {
091            return null;
092        }
093    
094        @Override
095        public void visitMaxs(int maxStack, int maxLocals) {
096    
097        }
098    
099        @Override
100        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
101            return null;
102        }
103    
104        @Override
105        public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
106            return null;
107        }
108    
109        //TODO not skip for lambdas
110        @Override
111        public void visitLineNumber(int line, Label start) {
112    
113        }
114    }