• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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