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