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.tree; 29 30 import java.util.ArrayList; 31 import java.util.List; 32 import org.objectweb.asm.ClassVisitor; 33 import org.objectweb.asm.ModuleVisitor; 34 import org.objectweb.asm.Opcodes; 35 36 /** 37 * A node that represents a module declaration. 38 * 39 * @author Remi Forax 40 */ 41 public class ModuleNode extends ModuleVisitor { 42 43 /** The fully qualified name (using dots) of this module. */ 44 public String name; 45 46 /** 47 * The module's access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code 48 * ACC_MANDATED}. 49 */ 50 public int access; 51 52 /** The version of this module. May be {@literal null}. */ 53 public String version; 54 55 /** 56 * The internal name of the main class of this module (see {@link 57 * org.objectweb.asm.Type#getInternalName()}). May be {@literal null}. 58 */ 59 public String mainClass; 60 61 /** 62 * The internal name of the packages declared by this module (see {@link 63 * org.objectweb.asm.Type#getInternalName()}). May be {@literal null}. 64 */ 65 public List<String> packages; 66 67 /** The dependencies of this module. May be {@literal null}. */ 68 public List<ModuleRequireNode> requires; 69 70 /** The packages exported by this module. May be {@literal null}. */ 71 public List<ModuleExportNode> exports; 72 73 /** The packages opened by this module. May be {@literal null}. */ 74 public List<ModuleOpenNode> opens; 75 76 /** 77 * The internal names of the services used by this module (see {@link 78 * org.objectweb.asm.Type#getInternalName()}). May be {@literal null}. 79 */ 80 public List<String> uses; 81 82 /** The services provided by this module. May be {@literal null}. */ 83 public List<ModuleProvideNode> provides; 84 85 /** 86 * Constructs a {@link ModuleNode}. <i>Subclasses must not use this constructor</i>. Instead, they 87 * must use the {@link #ModuleNode(int,String,int,String,List,List,List,List,List)} version. 88 * 89 * @param name the fully qualified name (using dots) of the module. 90 * @param access the module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code 91 * ACC_MANDATED}. 92 * @param version the module version, or {@literal null}. 93 * @throws IllegalStateException If a subclass calls this constructor. 94 */ ModuleNode(final String name, final int access, final String version)95 public ModuleNode(final String name, final int access, final String version) { 96 super(/* latest api = */ Opcodes.ASM9); 97 if (getClass() != ModuleNode.class) { 98 throw new IllegalStateException(); 99 } 100 this.name = name; 101 this.access = access; 102 this.version = version; 103 } 104 105 // TODO(forax): why is there no 'mainClass' and 'packages' parameters in this constructor? 106 /** 107 * Constructs a {@link ModuleNode}. 108 * 109 * @param api the ASM API version implemented by this visitor. Must be one of {@link 110 * Opcodes#ASM6}, {@link Opcodes#ASM7}, {@link Opcodes#ASM8} or {@link Opcodes#ASM9}. 111 * @param name the fully qualified name (using dots) of the module. 112 * @param access the module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code 113 * ACC_MANDATED}. 114 * @param version the module version, or {@literal null}. 115 * @param requires The dependencies of this module. May be {@literal null}. 116 * @param exports The packages exported by this module. May be {@literal null}. 117 * @param opens The packages opened by this module. May be {@literal null}. 118 * @param uses The internal names of the services used by this module (see {@link 119 * org.objectweb.asm.Type#getInternalName()}). May be {@literal null}. 120 * @param provides The services provided by this module. May be {@literal null}. 121 */ ModuleNode( final int api, final String name, final int access, final String version, final List<ModuleRequireNode> requires, final List<ModuleExportNode> exports, final List<ModuleOpenNode> opens, final List<String> uses, final List<ModuleProvideNode> provides)122 public ModuleNode( 123 final int api, 124 final String name, 125 final int access, 126 final String version, 127 final List<ModuleRequireNode> requires, 128 final List<ModuleExportNode> exports, 129 final List<ModuleOpenNode> opens, 130 final List<String> uses, 131 final List<ModuleProvideNode> provides) { 132 super(api); 133 this.name = name; 134 this.access = access; 135 this.version = version; 136 this.requires = requires; 137 this.exports = exports; 138 this.opens = opens; 139 this.uses = uses; 140 this.provides = provides; 141 } 142 143 @Override visitMainClass(final String mainClass)144 public void visitMainClass(final String mainClass) { 145 this.mainClass = mainClass; 146 } 147 148 @Override visitPackage(final String packaze)149 public void visitPackage(final String packaze) { 150 if (packages == null) { 151 packages = new ArrayList<>(5); 152 } 153 packages.add(packaze); 154 } 155 156 @Override visitRequire(final String module, final int access, final String version)157 public void visitRequire(final String module, final int access, final String version) { 158 if (requires == null) { 159 requires = new ArrayList<>(5); 160 } 161 requires.add(new ModuleRequireNode(module, access, version)); 162 } 163 164 @Override visitExport(final String packaze, final int access, final String... modules)165 public void visitExport(final String packaze, final int access, final String... modules) { 166 if (exports == null) { 167 exports = new ArrayList<>(5); 168 } 169 exports.add(new ModuleExportNode(packaze, access, Util.asArrayList(modules))); 170 } 171 172 @Override visitOpen(final String packaze, final int access, final String... modules)173 public void visitOpen(final String packaze, final int access, final String... modules) { 174 if (opens == null) { 175 opens = new ArrayList<>(5); 176 } 177 opens.add(new ModuleOpenNode(packaze, access, Util.asArrayList(modules))); 178 } 179 180 @Override visitUse(final String service)181 public void visitUse(final String service) { 182 if (uses == null) { 183 uses = new ArrayList<>(5); 184 } 185 uses.add(service); 186 } 187 188 @Override visitProvide(final String service, final String... providers)189 public void visitProvide(final String service, final String... providers) { 190 if (provides == null) { 191 provides = new ArrayList<>(5); 192 } 193 provides.add(new ModuleProvideNode(service, Util.asArrayList(providers))); 194 } 195 196 @Override visitEnd()197 public void visitEnd() { 198 // Nothing to do. 199 } 200 201 /** 202 * Makes the given class visitor visit this module. 203 * 204 * @param classVisitor a class visitor. 205 */ accept(final ClassVisitor classVisitor)206 public void accept(final ClassVisitor classVisitor) { 207 ModuleVisitor moduleVisitor = classVisitor.visitModule(name, access, version); 208 if (moduleVisitor == null) { 209 return; 210 } 211 if (mainClass != null) { 212 moduleVisitor.visitMainClass(mainClass); 213 } 214 if (packages != null) { 215 for (int i = 0, n = packages.size(); i < n; i++) { 216 moduleVisitor.visitPackage(packages.get(i)); 217 } 218 } 219 if (requires != null) { 220 for (int i = 0, n = requires.size(); i < n; i++) { 221 requires.get(i).accept(moduleVisitor); 222 } 223 } 224 if (exports != null) { 225 for (int i = 0, n = exports.size(); i < n; i++) { 226 exports.get(i).accept(moduleVisitor); 227 } 228 } 229 if (opens != null) { 230 for (int i = 0, n = opens.size(); i < n; i++) { 231 opens.get(i).accept(moduleVisitor); 232 } 233 } 234 if (uses != null) { 235 for (int i = 0, n = uses.size(); i < n; i++) { 236 moduleVisitor.visitUse(uses.get(i)); 237 } 238 } 239 if (provides != null) { 240 for (int i = 0, n = provides.size(); i < n; i++) { 241 provides.get(i).accept(moduleVisitor); 242 } 243 } 244 } 245 } 246