001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.asm;
016    
017    import java.lang.reflect.Method;
018    import java.lang.reflect.Modifier;
019    
020    import java.util.ArrayList;
021    import java.util.List;
022    
023    import org.objectweb.asm.Opcodes;
024    import org.objectweb.asm.Type;
025    import org.objectweb.asm.commons.GeneratorAdapter;
026    import org.objectweb.asm.tree.MethodNode;
027    
028    /**
029     * @author Shuyang Zhou
030     */
031    public class MethodNodeGenerator extends GeneratorAdapter {
032    
033            public MethodNodeGenerator(Method method) {
034                    this(_createMethodNode(method));
035            }
036    
037            public MethodNodeGenerator(MethodNode methodNode) {
038                    super(
039                            Opcodes.ASM5, methodNode, methodNode.access, methodNode.name,
040                            methodNode.desc);
041    
042                    _methodNode = methodNode;
043            }
044    
045            public MethodNode getMethodNode() {
046                    return _methodNode;
047            }
048    
049            public void invokeInterface(String owner, Method method) {
050                    super.visitMethodInsn(
051                            Opcodes.INVOKEINTERFACE, owner, method.getName(),
052                            Type.getMethodDescriptor(method), true);
053            }
054    
055            public void invokeInterface(
056                    String owner, String name, Type returnType, Type... argumentTypes) {
057    
058                    super.visitMethodInsn(
059                            Opcodes.INVOKEINTERFACE, owner, name,
060                            Type.getMethodDescriptor(returnType, argumentTypes), true);
061            }
062    
063            public void invokeSpecial(String owner, Method method) {
064                    super.visitMethodInsn(
065                            Opcodes.INVOKESPECIAL, owner, method.getName(),
066                            Type.getMethodDescriptor(method), false);
067            }
068    
069            public void invokeSpecial(
070                    String owner, String name, Type returnType, Type... argumentTypes) {
071    
072                    super.visitMethodInsn(
073                            Opcodes.INVOKESPECIAL, owner, name,
074                            Type.getMethodDescriptor(returnType, argumentTypes), false);
075            }
076    
077            public void invokeStatic(String owner, Method method) {
078                    super.visitMethodInsn(
079                            Opcodes.INVOKESTATIC, owner, method.getName(),
080                            Type.getMethodDescriptor(method), false);
081            }
082    
083            public void invokeStatic(
084                    String owner, String name, Type returnType, Type... argumentTypes) {
085    
086                    super.visitMethodInsn(
087                            Opcodes.INVOKESTATIC, owner, name,
088                            Type.getMethodDescriptor(returnType, argumentTypes), false);
089            }
090    
091            public void invokeVirtual(String owner, Method method) {
092                    super.visitMethodInsn(
093                            Opcodes.INVOKEVIRTUAL, owner, method.getName(),
094                            Type.getMethodDescriptor(method), false);
095            }
096    
097            public void invokeVirtual(
098                    String owner, String name, Type returnType, Type... argumentTypes) {
099    
100                    super.visitMethodInsn(
101                            Opcodes.INVOKEVIRTUAL, owner, name,
102                            Type.getMethodDescriptor(returnType, argumentTypes), false);
103            }
104    
105            public void visitMethodInsn(
106                    int opcode, String owner, String name, Type returnType,
107                    Type... argumentTypes) {
108    
109                    super.visitMethodInsn(
110                            opcode, owner, name,
111                            Type.getMethodDescriptor(returnType, argumentTypes), false);
112            }
113    
114            private static MethodNode _createMethodNode(Method method) {
115                    MethodNode methodNode = new MethodNode();
116    
117                    methodNode.access = method.getModifiers() & ~Modifier.ABSTRACT;
118                    methodNode.name = method.getName();
119                    methodNode.desc = Type.getMethodDescriptor(method);
120    
121                    List<String> exceptions = new ArrayList<>();
122    
123                    for (Class<?> exceptionClass : method.getExceptionTypes()) {
124                            exceptions.add(Type.getInternalName(exceptionClass));
125                    }
126    
127                    methodNode.exceptions = exceptions;
128    
129                    return methodNode;
130            }
131    
132            private final MethodNode _methodNode;
133    
134    }