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