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 org.springframework.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 public 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 @SuppressWarnings("deprecation") 069 public ModuleVisitor(final int api, final ModuleVisitor moduleVisitor) { 070 if (api != Opcodes.ASM7 071 && api != Opcodes.ASM6 072 && api != Opcodes.ASM5 073 && api != Opcodes.ASM4 074 && api != Opcodes.ASM8_EXPERIMENTAL) { 075 throw new IllegalArgumentException("Unsupported api " + api); 076 } 077 // SPRING PATCH: no preview mode check for ASM 8 experimental 078 this.api = api; 079 this.mv = moduleVisitor; 080 } 081 082 /** 083 * Visit the main class of the current module. 084 * 085 * @param mainClass the internal name of the main class of the current module. 086 */ 087 public void visitMainClass(final String mainClass) { 088 if (mv != null) { 089 mv.visitMainClass(mainClass); 090 } 091 } 092 093 /** 094 * Visit a package of the current module. 095 * 096 * @param packaze the internal name of a package. 097 */ 098 public void visitPackage(final String packaze) { 099 if (mv != null) { 100 mv.visitPackage(packaze); 101 } 102 } 103 104 /** 105 * Visits a dependence of the current module. 106 * 107 * @param module the fully qualified name (using dots) of the dependence. 108 * @param access the access flag of the dependence among {@code ACC_TRANSITIVE}, {@code 109 * ACC_STATIC_PHASE}, {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}. 110 * @param version the module version at compile time, or {@literal null}. 111 */ 112 public void visitRequire(final String module, final int access, final String version) { 113 if (mv != null) { 114 mv.visitRequire(module, access, version); 115 } 116 } 117 118 /** 119 * Visit an exported package of the current module. 120 * 121 * @param packaze the internal name of the exported package. 122 * @param access the access flag of the exported package, valid values are among {@code 123 * ACC_SYNTHETIC} and {@code ACC_MANDATED}. 124 * @param modules the fully qualified names (using dots) of the modules that can access the public 125 * classes of the exported package, or {@literal null}. 126 */ 127 public void visitExport(final String packaze, final int access, final String... modules) { 128 if (mv != null) { 129 mv.visitExport(packaze, access, modules); 130 } 131 } 132 133 /** 134 * Visit an open package of the current module. 135 * 136 * @param packaze the internal name of the opened package. 137 * @param access the access flag of the opened package, valid values are among {@code 138 * ACC_SYNTHETIC} and {@code ACC_MANDATED}. 139 * @param modules the fully qualified names (using dots) of the modules that can use deep 140 * reflection to the classes of the open package, or {@literal null}. 141 */ 142 public void visitOpen(final String packaze, final int access, final String... modules) { 143 if (mv != null) { 144 mv.visitOpen(packaze, access, modules); 145 } 146 } 147 148 /** 149 * Visit a service used by the current module. The name must be the internal name of an interface 150 * or a class. 151 * 152 * @param service the internal name of the service. 153 */ 154 public void visitUse(final String service) { 155 if (mv != null) { 156 mv.visitUse(service); 157 } 158 } 159 160 /** 161 * Visit an implementation of a service. 162 * 163 * @param service the internal name of the service. 164 * @param providers the internal names of the implementations of the service (there is at least 165 * one provider). 166 */ 167 public void visitProvide(final String service, final String... providers) { 168 if (mv != null) { 169 mv.visitProvide(service, providers); 170 } 171 } 172 173 /** 174 * Visits the end of the module. This method, which is the last one to be called, is used to 175 * inform the visitor that everything have been visited. 176 */ 177 public void visitEnd() { 178 if (mv != null) { 179 mv.visitEnd(); 180 } 181 } 182}