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