1 // ASM: a very small and fast Java bytecode manipulation framework 2 // Copyright (c) 2000-2011 INRIA, France Telecom 3 // All rights reserved. 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions 7 // are met: 8 // 1. Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // 2. Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // 3. Neither the name of the copyright holders nor the names of its 14 // contributors may be used to endorse or promote products derived from 15 // this software without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 // THE POSSIBILITY OF SUCH DAMAGE. 28 package org.objectweb.asm; 29 30 /** 31 * A visitor to visit a Java module. The methods of this class must be called in the following 32 * order: ( {@code visitMainClass} | ( {@code visitPackage} | {@code visitRequire} | {@code 33 * visitExport} | {@code visitOpen} | {@code visitUse} | {@code visitProvide} )* ) {@code visitEnd}. 34 * 35 * @author Remi Forax 36 * @author Eric Bruneton 37 */ 38 public abstract class ModuleVisitor { 39 /** 40 * The ASM API version implemented by this visitor. The value of this field must be one of {@link 41 * Opcodes#ASM6} or {@link Opcodes#ASM7}. 42 */ 43 protected final int api; 44 45 /** 46 * The module visitor to which this visitor must delegate method calls. May be {@literal null}. 47 */ 48 protected ModuleVisitor mv; 49 50 /** 51 * Constructs a new {@link ModuleVisitor}. 52 * 53 * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM6} 54 * or {@link Opcodes#ASM7}. 55 */ ModuleVisitor(final int api)56 protected ModuleVisitor(final int api) { 57 this(api, null); 58 } 59 60 /** 61 * Constructs a new {@link ModuleVisitor}. 62 * 63 * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM6} 64 * or {@link Opcodes#ASM7}. 65 * @param moduleVisitor the module visitor to which this visitor must delegate method calls. May 66 * be null. 67 */ ModuleVisitor(final int api, final ModuleVisitor moduleVisitor)68 protected ModuleVisitor(final int api, final ModuleVisitor moduleVisitor) { 69 if (api != Opcodes.ASM9 70 && api != Opcodes.ASM8 71 && api != Opcodes.ASM7 72 && api != Opcodes.ASM6 73 && api != Opcodes.ASM5 74 && api != Opcodes.ASM4 75 && api != Opcodes.ASM10_EXPERIMENTAL) { 76 throw new IllegalArgumentException("Unsupported api " + api); 77 } 78 if (api == Opcodes.ASM10_EXPERIMENTAL) { 79 Constants.checkAsmExperimental(this); 80 } 81 this.api = api; 82 this.mv = moduleVisitor; 83 } 84 85 /** 86 * The module visitor to which this visitor must delegate method calls. May be {@literal null}. 87 * 88 * @return the module visitor to which this visitor must delegate method calls, or {@literal 89 * null}. 90 */ getDelegate()91 public ModuleVisitor getDelegate() { 92 return mv; 93 } 94 95 /** 96 * Visit the main class of the current module. 97 * 98 * @param mainClass the internal name of the main class of the current module (see {@link 99 * Type#getInternalName()}). 100 */ visitMainClass(final String mainClass)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 */ visitPackage(final String packaze)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 */ visitRequire(final String module, final int access, final String version)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 */ visitExport(final String packaze, final int access, final String... modules)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 */ visitOpen(final String packaze, final int access, final String... modules)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 */ visitUse(final String service)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 */ visitProvide(final String service, final String... providers)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 */ visitEnd()191 public void visitEnd() { 192 if (mv != null) { 193 mv.visitEnd(); 194 } 195 } 196 } 197