* ProGuard -- shrinking, optimization, obfuscation, and preverification
 *             of Java bytecode.
 * Copyright (c) 2002-2020 Guardsquare NV
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package proguard.optimize.gson;

import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
import proguard.classfile.editor.*;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.*;

import static proguard.classfile.instruction.Instruction.OP_ARETURN;
import static proguard.classfile.instruction.Instruction.OP_RETURN;

 * Instruction visitor that adds some instrumentation code to the Gson.toJson()
 * and Gson.fromJson() methods that prints out the type adapter cache. This
 * can be useful for debugging purposes.
 * @author Lars Vandenbergh
public class GsonInstrumentationAdder
implements   InstructionVisitor
    private static final boolean DEBUG = false;

    private final ClassPool           programClassPool;
    private final ClassPool           libraryClassPool;
    private final CodeAttributeEditor codeAttributeEditor;

     * Creates a new GsonInstrumentationAdder.
     * @param programClassPool     the program class pool used for looking up
     *                             program class references.
     * @param libraryClassPool     the library class pool used for looking up
     *                             library class references.
     * @param codeAttributeEditor  the code attribute editor used for editing
     *                             the code attribute of the Gson methods.
    public GsonInstrumentationAdder(ClassPool           programClassPool,
                                    ClassPool           libraryClassPool,
                                    CodeAttributeEditor codeAttributeEditor)
        this.programClassPool    = programClassPool;
        this.libraryClassPool    = libraryClassPool;
        this.codeAttributeEditor = codeAttributeEditor;

    // Implementations for InstructionVisitor.

    public void visitAnyInstruction(Clazz         clazz,
                                    Method        method,
                                    CodeAttribute codeAttribute,
                                    int           offset,
                                    Instruction   instruction)
        if (instruction.actualOpcode() == OP_RETURN ||
            instruction.actualOpcode() == OP_ARETURN)
            String fullyQualifiedMethodName = clazz.getName() + "#" +
                                              method.getName(clazz) + method.getDescriptor(clazz);
            if (DEBUG)
                System.out.println("GsonInstrumentationAdder: instrumenting " +

            InstructionSequenceBuilder ____ = new InstructionSequenceBuilder((ProgramClass)clazz,
            ____.ldc("Type token cache after invoking " + fullyQualifiedMethodName + ":")

            codeAttributeEditor.insertBeforeInstruction(offset, ____.instructions());