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 * The module visitor to which this visitor must delegate method calls. May be {@literal null}. 087 * 088 * @return the module visitor to which this visitor must delegate method calls, or {@literal 089 * null}. 090 */ 091 public ModuleVisitor getDelegate() { 092 return mv; 093 } 094 095 /** 096 * Visit the main class of the current module. 097 * 098 * @param mainClass the internal name of the main class of the current module (see {@link 099 * Type#getInternalName()}). 100 */ 101 public void visitMainClass(final String mainClass) { 102 if (mv != null) { 103 mv.visitMainClass(mainClass); 104 } 105 } 106 107 /** 108 * Visit a package of the current module. 109 * 110 * @param packaze the internal name of a package (see {@link Type#getInternalName()}). 111 */ 112 public void visitPackage(final String packaze) { 113 if (mv != null) { 114 mv.visitPackage(packaze); 115 } 116 } 117 118 /** 119 * Visits a dependence of the current module. 120 * 121 * @param module the fully qualified name (using dots) of the dependence. 122 * @param access the access flag of the dependence among {@code ACC_TRANSITIVE}, {@code 123 * ACC_STATIC_PHASE}, {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}. 124 * @param version the module version at compile time, or {@literal null}. 125 */ 126 public void visitRequire(final String module, final int access, final String version) { 127 if (mv != null) { 128 mv.visitRequire(module, access, version); 129 } 130 } 131 132 /** 133 * Visit an exported package of the current module. 134 * 135 * @param packaze the internal name of the exported package (see {@link Type#getInternalName()}). 136 * @param access the access flag of the exported package, valid values are among {@code 137 * ACC_SYNTHETIC} and {@code ACC_MANDATED}. 138 * @param modules the fully qualified names (using dots) of the modules that can access the public 139 * classes of the exported package, or {@literal null}. 140 */ 141 public void visitExport(final String packaze, final int access, final String... modules) { 142 if (mv != null) { 143 mv.visitExport(packaze, access, modules); 144 } 145 } 146 147 /** 148 * Visit an open package of the current module. 149 * 150 * @param packaze the internal name of the opened package (see {@link Type#getInternalName()}). 151 * @param access the access flag of the opened package, valid values are among {@code 152 * ACC_SYNTHETIC} and {@code ACC_MANDATED}. 153 * @param modules the fully qualified names (using dots) of the modules that can use deep 154 * reflection to the classes of the open package, or {@literal null}. 155 */ 156 public void visitOpen(final String packaze, final int access, final String... modules) { 157 if (mv != null) { 158 mv.visitOpen(packaze, access, modules); 159 } 160 } 161 162 /** 163 * Visit a service used by the current module. The name must be the internal name of an interface 164 * or a class. 165 * 166 * @param service the internal name of the service (see {@link Type#getInternalName()}). 167 */ 168 public void visitUse(final String service) { 169 if (mv != null) { 170 mv.visitUse(service); 171 } 172 } 173 174 /** 175 * Visit an implementation of a service. 176 * 177 * @param service the internal name of the service (see {@link Type#getInternalName()}). 178 * @param providers the internal names (see {@link Type#getInternalName()}) of the implementations 179 * of the service (there is at least one provider). 180 */ 181 public void visitProvide(final String service, final String... providers) { 182 if (mv != null) { 183 mv.visitProvide(service, providers); 184 } 185 } 186 187 /** 188 * Visits the end of the module. This method, which is the last one to be called, is used to 189 * inform the visitor that everything have been visited. 190 */ 191 public void visitEnd() { 192 if (mv != null) { 193 mv.visitEnd(); 194 } 195 } 196}