001// ASM: a very small and fast Java bytecode manipulation framework 002// Copyright (c) 2000-2011 INRIA, France Telecom 003// All rights reserved. 004// 005// Redistribution and use in source and binary forms, with or without 006// modification, are permitted provided that the following conditions 007// are met: 008// 1. Redistributions of source code must retain the above copyright 009// notice, this list of conditions and the following disclaimer. 010// 2. Redistributions in binary form must reproduce the above copyright 011// notice, this list of conditions and the following disclaimer in the 012// documentation and/or other materials provided with the distribution. 013// 3. Neither the name of the copyright holders nor the names of its 014// contributors may be used to endorse or promote products derived from 015// this software without specific prior written permission. 016// 017// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 018// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 019// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 020// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 021// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 022// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 023// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 024// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 025// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 026// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 027// THE POSSIBILITY OF SUCH DAMAGE. 028package io.ebean.enhance.asm; 029 030/** 031 * A visitor to visit a Java module. The methods of this class must be called in the following 032 * order: ( {@code visitMainClass} | ( {@code visitPackage} | {@code visitRequire} | {@code 033 * visitExport} | {@code visitOpen} | {@code visitUse} | {@code visitProvide} )* ) {@code visitEnd}. 034 * 035 * @author Remi Forax 036 * @author Eric Bruneton 037 */ 038public abstract class ModuleVisitor { 039 /** 040 * The ASM API version implemented by this visitor. The value of this field must be one of {@link 041 * Opcodes#ASM6} or {@link Opcodes#ASM7}. 042 */ 043 protected final int api; 044 045 /** 046 * The module visitor to which this visitor must delegate method calls. May be {@literal null}. 047 */ 048 protected ModuleVisitor mv; 049 050 /** 051 * Constructs a new {@link ModuleVisitor}. 052 * 053 * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM6} 054 * or {@link Opcodes#ASM7}. 055 */ 056 protected ModuleVisitor(final int api) { 057 this(api, null); 058 } 059 060 /** 061 * Constructs a new {@link ModuleVisitor}. 062 * 063 * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM6} 064 * or {@link Opcodes#ASM7}. 065 * @param moduleVisitor the module visitor to which this visitor must delegate method calls. May 066 * be null. 067 */ 068 protected ModuleVisitor(final int api, final ModuleVisitor moduleVisitor) { 069 if (api != Opcodes.ASM9 070 && api != Opcodes.ASM8 071 && api != Opcodes.ASM7 072 && api != Opcodes.ASM6 073 && api != Opcodes.ASM5 074 && api != Opcodes.ASM4 075 && api != Opcodes.ASM10_EXPERIMENTAL) { 076 throw new IllegalArgumentException("Unsupported api " + api); 077 } 078 if (api == Opcodes.ASM10_EXPERIMENTAL) { 079 Constants.checkAsmExperimental(this); 080 } 081 this.api = api; 082 this.mv = moduleVisitor; 083 } 084 085 /** 086 * Visit the main class of the current module. 087 * 088 * @param mainClass the internal name of the main class of the current module. 089 */ 090 public void visitMainClass(final String mainClass) { 091 if (mv != null) { 092 mv.visitMainClass(mainClass); 093 } 094 } 095 096 /** 097 * Visit a package of the current module. 098 * 099 * @param packaze the internal name of a package. 100 */ 101 public void visitPackage(final String packaze) { 102 if (mv != null) { 103 mv.visitPackage(packaze); 104 } 105 } 106 107 /** 108 * Visits a dependence of the current module. 109 * 110 * @param module the fully qualified name (using dots) of the dependence. 111 * @param access the access flag of the dependence among {@code ACC_TRANSITIVE}, {@code 112 * ACC_STATIC_PHASE}, {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}. 113 * @param version the module version at compile time, or {@literal null}. 114 */ 115 public void visitRequire(final String module, final int access, final String version) { 116 if (mv != null) { 117 mv.visitRequire(module, access, version); 118 } 119 } 120 121 /** 122 * Visit an exported package of the current module. 123 * 124 * @param packaze the internal name of the exported package. 125 * @param access the access flag of the exported package, valid values are among {@code 126 * ACC_SYNTHETIC} and {@code ACC_MANDATED}. 127 * @param modules the fully qualified names (using dots) of the modules that can access the public 128 * classes of the exported package, or {@literal null}. 129 */ 130 public void visitExport(final String packaze, final int access, final String... modules) { 131 if (mv != null) { 132 mv.visitExport(packaze, access, modules); 133 } 134 } 135 136 /** 137 * Visit an open package of the current module. 138 * 139 * @param packaze the internal name of the opened package. 140 * @param access the access flag of the opened package, valid values are among {@code 141 * ACC_SYNTHETIC} and {@code ACC_MANDATED}. 142 * @param modules the fully qualified names (using dots) of the modules that can use deep 143 * reflection to the classes of the open package, or {@literal null}. 144 */ 145 public void visitOpen(final String packaze, final int access, final String... modules) { 146 if (mv != null) { 147 mv.visitOpen(packaze, access, modules); 148 } 149 } 150 151 /** 152 * Visit a service used by the current module. The name must be the internal name of an interface 153 * or a class. 154 * 155 * @param service the internal name of the service. 156 */ 157 public void visitUse(final String service) { 158 if (mv != null) { 159 mv.visitUse(service); 160 } 161 } 162 163 /** 164 * Visit an implementation of a service. 165 * 166 * @param service the internal name of the service. 167 * @param providers the internal names of the implementations of the service (there is at least 168 * one provider). 169 */ 170 public void visitProvide(final String service, final String... providers) { 171 if (mv != null) { 172 mv.visitProvide(service, providers); 173 } 174 } 175 176 /** 177 * Visits the end of the module. This method, which is the last one to be called, is used to 178 * inform the visitor that everything have been visited. 179 */ 180 public void visitEnd() { 181 if (mv != null) { 182 mv.visitEnd(); 183 } 184 } 185}