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