1/*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation.  Oracle designates this
7 * particular file as subject to the "Classpath" exception as provided
8 * by Oracle in the LICENSE file that accompanied this code.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25/*
26 * This file is available under and governed by the GNU General Public
27 * License version 2 only, as published by the Free Software Foundation.
28 * However, the following notice accompanied the original version of this
29 * file:
30 *
31 * ASM: a very small and fast Java bytecode manipulation framework
32 * Copyright (c) 2000-2011 INRIA, France Telecom
33 * All rights reserved.
34 *
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
37 * are met:
38 * 1. Redistributions of source code must retain the above copyright
39 *    notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 *    notice, this list of conditions and the following disclaimer in the
42 *    documentation and/or other materials provided with the distribution.
43 * 3. Neither the name of the copyright holders nor the names of its
44 *    contributors may be used to endorse or promote products derived from
45 *    this software without specific prior written permission.
46 *
47 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
48 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
51 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
52 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
53 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
54 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
55 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
56 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
57 * THE POSSIBILITY OF SUCH DAMAGE.
58 */
59
60package jdk.internal.org.objectweb.asm.commons;
61
62import jdk.internal.org.objectweb.asm.AnnotationVisitor;
63import jdk.internal.org.objectweb.asm.Handle;
64import jdk.internal.org.objectweb.asm.Label;
65import jdk.internal.org.objectweb.asm.MethodVisitor;
66import jdk.internal.org.objectweb.asm.Opcodes;
67import jdk.internal.org.objectweb.asm.TypePath;
68
69/**
70 * A {@link LocalVariablesSorter} for type mapping.
71 *
72 * @deprecated use {@link MethodRemapper} instead.
73 * @author Eugene Kuleshov
74 */
75@Deprecated
76public class RemappingMethodAdapter extends LocalVariablesSorter {
77
78    protected final Remapper remapper;
79
80    public RemappingMethodAdapter(final int access, final String desc,
81            final MethodVisitor mv, final Remapper remapper) {
82        this(Opcodes.ASM5, access, desc, mv, remapper);
83    }
84
85    protected RemappingMethodAdapter(final int api, final int access,
86            final String desc, final MethodVisitor mv, final Remapper remapper) {
87        super(api, access, desc, mv);
88        this.remapper = remapper;
89    }
90
91    @Override
92    public AnnotationVisitor visitAnnotationDefault() {
93        AnnotationVisitor av = super.visitAnnotationDefault();
94        return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
95    }
96
97    @Override
98    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
99        AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc),
100                visible);
101        return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
102    }
103
104    @Override
105    public AnnotationVisitor visitTypeAnnotation(int typeRef,
106            TypePath typePath, String desc, boolean visible) {
107        AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath,
108                remapper.mapDesc(desc), visible);
109        return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
110    }
111
112    @Override
113    public AnnotationVisitor visitParameterAnnotation(int parameter,
114            String desc, boolean visible) {
115        AnnotationVisitor av = super.visitParameterAnnotation(parameter,
116                remapper.mapDesc(desc), visible);
117        return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
118    }
119
120    @Override
121    public void visitFrame(int type, int nLocal, Object[] local, int nStack,
122            Object[] stack) {
123        super.visitFrame(type, nLocal, remapEntries(nLocal, local), nStack,
124                remapEntries(nStack, stack));
125    }
126
127    private Object[] remapEntries(int n, Object[] entries) {
128        for (int i = 0; i < n; i++) {
129            if (entries[i] instanceof String) {
130                Object[] newEntries = new Object[n];
131                if (i > 0) {
132                    System.arraycopy(entries, 0, newEntries, 0, i);
133                }
134                do {
135                    Object t = entries[i];
136                    newEntries[i++] = t instanceof String ? remapper
137                            .mapType((String) t) : t;
138                } while (i < n);
139                return newEntries;
140            }
141        }
142        return entries;
143    }
144
145    @Override
146    public void visitFieldInsn(int opcode, String owner, String name,
147            String desc) {
148        super.visitFieldInsn(opcode, remapper.mapType(owner),
149                remapper.mapFieldName(owner, name, desc),
150                remapper.mapDesc(desc));
151    }
152
153    @Deprecated
154    @Override
155    public void visitMethodInsn(final int opcode, final String owner,
156            final String name, final String desc) {
157        if (api >= Opcodes.ASM5) {
158            super.visitMethodInsn(opcode, owner, name, desc);
159            return;
160        }
161        doVisitMethodInsn(opcode, owner, name, desc,
162                opcode == Opcodes.INVOKEINTERFACE);
163    }
164
165    @Override
166    public void visitMethodInsn(final int opcode, final String owner,
167            final String name, final String desc, final boolean itf) {
168        if (api < Opcodes.ASM5) {
169            super.visitMethodInsn(opcode, owner, name, desc, itf);
170            return;
171        }
172        doVisitMethodInsn(opcode, owner, name, desc, itf);
173    }
174
175    private void doVisitMethodInsn(int opcode, String owner, String name,
176            String desc, boolean itf) {
177        // Calling super.visitMethodInsn requires to call the correct version
178        // depending on this.api (otherwise infinite loops can occur). To
179        // simplify and to make it easier to automatically remove the backward
180        // compatibility code, we inline the code of the overridden method here.
181        // IMPORTANT: THIS ASSUMES THAT visitMethodInsn IS NOT OVERRIDDEN IN
182        // LocalVariableSorter.
183        if (mv != null) {
184            mv.visitMethodInsn(opcode, remapper.mapType(owner),
185                    remapper.mapMethodName(owner, name, desc),
186                    remapper.mapMethodDesc(desc), itf);
187        }
188    }
189
190    @Override
191    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
192            Object... bsmArgs) {
193        for (int i = 0; i < bsmArgs.length; i++) {
194            bsmArgs[i] = remapper.mapValue(bsmArgs[i]);
195        }
196        super.visitInvokeDynamicInsn(
197                remapper.mapInvokeDynamicMethodName(name, desc),
198                remapper.mapMethodDesc(desc), (Handle) remapper.mapValue(bsm),
199                bsmArgs);
200    }
201
202    @Override
203    public void visitTypeInsn(int opcode, String type) {
204        super.visitTypeInsn(opcode, remapper.mapType(type));
205    }
206
207    @Override
208    public void visitLdcInsn(Object cst) {
209        super.visitLdcInsn(remapper.mapValue(cst));
210    }
211
212    @Override
213    public void visitMultiANewArrayInsn(String desc, int dims) {
214        super.visitMultiANewArrayInsn(remapper.mapDesc(desc), dims);
215    }
216
217    @Override
218    public AnnotationVisitor visitInsnAnnotation(int typeRef,
219            TypePath typePath, String desc, boolean visible) {
220        AnnotationVisitor av = super.visitInsnAnnotation(typeRef, typePath,
221                remapper.mapDesc(desc), visible);
222        return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
223    }
224
225    @Override
226    public void visitTryCatchBlock(Label start, Label end, Label handler,
227            String type) {
228        super.visitTryCatchBlock(start, end, handler, type == null ? null
229                : remapper.mapType(type));
230    }
231
232    @Override
233    public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
234            TypePath typePath, String desc, boolean visible) {
235        AnnotationVisitor av = super.visitTryCatchAnnotation(typeRef, typePath,
236                remapper.mapDesc(desc), visible);
237        return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
238    }
239
240    @Override
241    public void visitLocalVariable(String name, String desc, String signature,
242            Label start, Label end, int index) {
243        super.visitLocalVariable(name, remapper.mapDesc(desc),
244                remapper.mapSignature(signature, true), start, end, index);
245    }
246
247    @Override
248    public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
249            TypePath typePath, Label[] start, Label[] end, int[] index,
250            String desc, boolean visible) {
251        AnnotationVisitor av = super.visitLocalVariableAnnotation(typeRef,
252                typePath, start, end, index, remapper.mapDesc(desc), visible);
253        return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
254    }
255}
256