1 /*
2  * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package javax.lang.model.element;
27 
28 import java.util.List;
29 import javax.lang.model.type.TypeMirror;
30 
31 /**
32  * Represents a module program element.  Provides access to
33  * information about the module, its directives, and its members.
34  *
35  * @see javax.lang.model.util.Elements#getModuleOf
36  * @since 9
37  * @jls 7.7 Module Declarations
38  */
39 public interface ModuleElement extends Element, QualifiedNameable {
40     /**
41      * {@return a {@linkplain javax.lang.model.type.NoType pseudo-type}
42      * for this module}
43      *
44      * @see javax.lang.model.type.NoType
45      * @see javax.lang.model.type.TypeKind#MODULE
46      */
47     @Override
asType()48     TypeMirror asType();
49 
50     /**
51      * Returns the fully qualified name of this module.  For an
52      * {@linkplain #isUnnamed() unnamed module}, an <a
53      * href=Name.html#empty_name>empty name</a> is returned.
54      *
55      * @apiNote If the module name consists of one identifier, then
56      * this method returns that identifier, which is deemed to be
57      * module's fully qualified name despite not being in qualified
58      * form.  If the module name consists of more than one identifier,
59      * then this method returns the entire name.
60      *
61      * @return the fully qualified name of this module, or an
62      * empty name if this is an unnamed module
63      *
64      * @jls 6.2 Names and Identifiers
65      */
66     @Override
getQualifiedName()67     Name getQualifiedName();
68 
69     /**
70      * Returns the simple name of this module.  For an {@linkplain
71      * #isUnnamed() unnamed module}, an <a
72      * href=Name.html#empty_name>empty name</a> is returned.
73      *
74      * @apiNote If the module name consists of one identifier, then
75      * this method returns that identifier.  If the module name
76      * consists of more than one identifier, then this method returns
77      * the rightmost such identifier, which is deemed to be the
78      * module's simple name.
79      *
80      * @return the simple name of this module or an empty name if
81      * this is an unnamed module
82      *
83      * @jls 6.2 Names and Identifiers
84      */
85     @Override
getSimpleName()86     Name getSimpleName();
87 
88     /**
89      * {@return the packages within this module}
90      */
91     @Override
getEnclosedElements()92     List<? extends Element> getEnclosedElements();
93 
94     /**
95      * {@return {@code true} if this is an open module and {@code
96      * false} otherwise}
97      */
isOpen()98     boolean isOpen();
99 
100     /**
101      * {@return {@code true} if this is an unnamed module and {@code
102      * false} otherwise}
103      *
104      * @jls 7.7.5 Unnamed Modules
105      */
isUnnamed()106     boolean isUnnamed();
107 
108     /**
109      * Returns {@code null} since a module is not enclosed by another
110      * element.
111      *
112      * @return {@code null}
113      */
114     @Override
getEnclosingElement()115     Element getEnclosingElement();
116 
117     /**
118      * Returns the directives contained in the declaration of this module.
119      * @return  the directives in the declaration of this module
120      */
getDirectives()121     List<? extends Directive> getDirectives();
122 
123     /**
124      * The {@code kind} of a directive.
125      *
126      * <p>Note that it is possible additional directive kinds will be added
127      * to accommodate new, currently unknown, language structures added to
128      * future versions of the Java programming language.
129      *
130      * @since 9
131      */
132     enum DirectiveKind {
133         /** A "requires (static|transitive)* module-name" directive. */
134         REQUIRES,
135         /** An "exports package-name [to module-name-list]" directive. */
136         EXPORTS,
137         /** An "opens package-name [to module-name-list]" directive. */
138         OPENS,
139         /** A "uses service-name" directive. */
140         USES,
141         /** A "provides service-name with implementation-name" directive. */
142         PROVIDES
143     };
144 
145     /**
146      * Represents a directive within the declaration of this
147      * module. The directives of a module declaration configure the
148      * module in the Java Platform Module System.
149      *
150      * @since 9
151      */
152     interface Directive {
153         /**
154          * {@return the {@code kind} of this directive}
155          * <ul>
156          *
157          * <li> The kind of a {@linkplain RequiresDirective requires
158          * directive} is {@link DirectiveKind#REQUIRES REQUIRES}.
159          *
160          * <li> The kind of an {@linkplain ExportsDirective exports
161          * directive} is {@link DirectiveKind#EXPORTS EXPORTS}.
162          *
163          * <li> The kind of an {@linkplain OpensDirective opens
164          * directive} is {@link DirectiveKind#OPENS OPENS}.
165          *
166          * <li> The kind of a {@linkplain UsesDirective uses
167          * directive} is {@link DirectiveKind#USES USES}.
168          *
169          * <li> The kind of a {@linkplain ProvidesDirective provides
170          * directive} is {@link DirectiveKind#PROVIDES PROVIDES}.
171          *
172          * </ul>
173          */
getKind()174         DirectiveKind getKind();
175 
176         /**
177          * Applies a visitor to this directive.
178          *
179          * @param <R> the return type of the visitor's methods
180          * @param <P> the type of the additional parameter to the visitor's methods
181          * @param v   the visitor operating on this directive
182          * @param p   additional parameter to the visitor
183          * @return a visitor-specified result
184          */
accept(DirectiveVisitor<R, P> v, P p)185         <R, P> R accept(DirectiveVisitor<R, P> v, P p);
186     }
187 
188     /**
189      * A visitor of module directives, in the style of the visitor design
190      * pattern.  Classes implementing this interface are used to operate
191      * on a directive when the kind of directive is unknown at compile time.
192      * When a visitor is passed to a directive's {@link Directive#accept
193      * accept} method, the <code>visit<i>Xyz</i></code> method applicable
194      * to that directive is invoked.
195      *
196      * <p> Classes implementing this interface may or may not throw a
197      * {@code NullPointerException} if the additional parameter {@code p}
198      * is {@code null}; see documentation of the implementing class for
199      * details.
200      *
201      * <p> <b>WARNING:</b> It is possible that methods will be added to
202      * this interface to accommodate new, currently unknown, language
203      * structures added to future versions of the Java programming
204      * language. Methods to accommodate new language constructs will
205      * be added in a source <em>compatible</em> way using
206      * <em>default methods</em>.
207      *
208      * @param <R> the return type of this visitor's methods.  Use {@link
209      *            Void} for visitors that do not need to return results.
210      * @param <P> the type of the additional parameter to this visitor's
211      *            methods.  Use {@code Void} for visitors that do not need an
212      *            additional parameter.
213      *
214      * @since 9
215      */
216     interface DirectiveVisitor<R, P> {
217         /**
218          * Visits any directive as if by passing itself to that
219          * directive's {@link Directive#accept accept} method and passing
220          * {@code null} for the additional parameter.
221          *
222          * @param d  the directive to visit
223          * @return a visitor-specified result
224          * @implSpec The default implementation is {@code d.accept(v, null)}.
225          */
visit(Directive d)226         default R visit(Directive d) {
227             return d.accept(this, null);
228         }
229 
230         /**
231          * Visits any directive as if by passing itself to that
232          * directive's {@link Directive#accept accept} method.
233          *
234          * @param d  the directive to visit
235          * @param p  a visitor-specified parameter
236          * @return a visitor-specified result
237          * @implSpec The default implementation is {@code d.accept(v, p)}.
238          */
visit(Directive d, P p)239         default R visit(Directive d, P p) {
240             return d.accept(this, p);
241         }
242 
243         /**
244          * Visits a {@code requires} directive.
245          * @param d  the directive to visit
246          * @param p  a visitor-specified parameter
247          * @return a visitor-specified result
248          */
visitRequires(RequiresDirective d, P p)249         R visitRequires(RequiresDirective d, P p);
250 
251         /**
252          * Visits an {@code exports} directive.
253          * @param d  the directive to visit
254          * @param p  a visitor-specified parameter
255          * @return a visitor-specified result
256          */
visitExports(ExportsDirective d, P p)257         R visitExports(ExportsDirective d, P p);
258 
259         /**
260          * Visits an {@code opens} directive.
261          * @param d  the directive to visit
262          * @param p  a visitor-specified parameter
263          * @return a visitor-specified result
264          */
visitOpens(OpensDirective d, P p)265         R visitOpens(OpensDirective d, P p);
266 
267         /**
268          * Visits a {@code uses} directive.
269          * @param d  the directive to visit
270          * @param p  a visitor-specified parameter
271          * @return a visitor-specified result
272          */
visitUses(UsesDirective d, P p)273         R visitUses(UsesDirective d, P p);
274 
275         /**
276          * Visits a {@code provides} directive.
277          * @param d  the directive to visit
278          * @param p  a visitor-specified parameter
279          * @return a visitor-specified result
280          */
visitProvides(ProvidesDirective d, P p)281         R visitProvides(ProvidesDirective d, P p);
282 
283         /**
284          * Visits an unknown directive.
285          * This can occur if the language evolves and new kinds of directive are added.
286          * @param d  the directive to visit
287          * @param p  a visitor-specified parameter
288          * @return a visitor-specified result
289          * @throws UnknownDirectiveException a visitor implementation may optionally throw this exception
290          * @implSpec The default implementation throws {@code new UnknownDirectiveException(d, p)}.
291          */
visitUnknown(Directive d, P p)292         default R visitUnknown(Directive d, P p) {
293             throw new UnknownDirectiveException(d, p);
294         }
295     }
296 
297     /**
298      * A dependency of a module.
299      * @since 9
300      */
301     interface RequiresDirective extends Directive {
302         /**
303          * {@return whether or not this is a static dependency}
304          */
isStatic()305         boolean isStatic();
306 
307         /**
308          * {@return whether or not this is a transitive dependency}
309          */
isTransitive()310         boolean isTransitive();
311 
312         /**
313          * {@return the module that is required}
314          */
getDependency()315         ModuleElement getDependency();
316     }
317 
318     /**
319      * An exported package of a module.
320      * @since 9
321      */
322     interface ExportsDirective extends Directive {
323 
324         /**
325          * {@return the package being exported}
326          */
getPackage()327         PackageElement getPackage();
328 
329         /**
330          * Returns the specific modules to which the package is being exported,
331          * or {@code null}, if the package is exported to all modules which
332          * have readability to this module.
333          * @return the specific modules to which the package is being exported
334          */
getTargetModules()335         List<? extends ModuleElement> getTargetModules();
336     }
337 
338     /**
339      * An opened package of a module.
340      * @since 9
341      */
342     interface OpensDirective extends Directive {
343 
344         /**
345          * {@return the package being opened}
346          */
getPackage()347         PackageElement getPackage();
348 
349         /**
350          * Returns the specific modules to which the package is being open
351          * or {@code null}, if the package is open all modules which
352          * have readability to this module.
353          * @return the specific modules to which the package is being opened
354          */
getTargetModules()355         List<? extends ModuleElement> getTargetModules();
356     }
357 
358     /**
359      * An implementation of a service provided by a module.
360      * @since 9
361      */
362     interface ProvidesDirective extends Directive {
363         /**
364          * {@return the service being provided}
365          */
getService()366         TypeElement getService();
367 
368         /**
369          * {@return the implementations of the service being provided}
370          */
getImplementations()371         List<? extends TypeElement> getImplementations();
372     }
373 
374     /**
375      * A reference to a service used by a module.
376      * @since 9
377      */
378     interface UsesDirective extends Directive {
379         /**
380          * {@return the service that is used}
381          */
getService()382         TypeElement getService();
383     }
384 }
385