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