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
  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
  75     Name getSimpleName();
  76 
  77     /**
  78      * Returns the packages within this module.
  79      * @return the packages within this module
  80      */
  81     @Override
  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      */
  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      */
 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
 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      */
 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          */
 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          */
 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          * The invocation {@code v.visit(d)} is equivalent to
 205          * {@code d.accept(v, null)}.
 206          * @param d  the directive to visit
 207          * @return a visitor-specified result
 208          * @implSpec This implementation is {@code visit(d, null)}
 209          */
 210         default R visit(Directive d) {
 211             return d.accept(this, null);
 212         }
 213 
 214         /**
 215          * Visits any directive as if by passing itself to that
 216          * directive's {@link Directive#accept accept} method.
 217          * The invocation {@code v.visit(d, p)} is equivalent to
 218          * {@code d.accept(v, p)}.
 219          * @param d  the directive to visit
 220          * @param p  a visitor-specified parameter
 221          * @return a visitor-specified result
 222          */
 223         default R visit(Directive d, P p) {
 224             return d.accept(this, p);
 225         }
 226 
 227         /**
 228          * Visits a {@code requires} directive.
 229          * @param d  the directive to visit
 230          * @param p  a visitor-specified parameter
 231          * @return a visitor-specified result
 232          */
 233         R visitRequires(RequiresDirective d, P p);
 234 
 235         /**
 236          * Visits an {@code exports} directive.
 237          * @param d  the directive to visit
 238          * @param p  a visitor-specified parameter
 239          * @return a visitor-specified result
 240          */
 241         R visitExports(ExportsDirective d, P p);
 242 
 243         /**
 244          * Visits an {@code opens} directive.
 245          * @param d  the directive to visit
 246          * @param p  a visitor-specified parameter
 247          * @return a visitor-specified result
 248          */
 249         R visitOpens(OpensDirective d, P p);
 250 
 251         /**
 252          * Visits a {@code uses} directive.
 253          * @param d  the directive to visit
 254          * @param p  a visitor-specified parameter
 255          * @return a visitor-specified result
 256          */
 257         R visitUses(UsesDirective d, P p);
 258 
 259         /**
 260          * Visits a {@code provides} directive.
 261          * @param d  the directive to visit
 262          * @param p  a visitor-specified parameter
 263          * @return a visitor-specified result
 264          */
 265         R visitProvides(ProvidesDirective d, P p);
 266 
 267         /**
 268          * Visits an unknown directive.
 269          * This can occur if the language evolves and new kinds of directive are added.
 270          * @param d  the directive to visit
 271          * @param p  a visitor-specified parameter
 272          * @return a visitor-specified result
 273          * @throws UnknownDirectiveException a visitor implementation may optionally throw this exception
 274          * @implSpec This implementation throws {@code new UnknownDirectiveException(d, p)}.
 275          */
 276         default R visitUnknown(Directive d, P p) {
 277             throw new UnknownDirectiveException(d, p);
 278         }
 279     }
 280 
 281     /**
 282      * A dependency of a module.
 283      * @since 9
 284      * @spec JPMS
 285      */
 286     interface RequiresDirective extends Directive {
 287         /**
 288          * Returns whether or not this is a static dependency.
 289          * @return whether or not this is a static dependency
 290          */
 291         boolean isStatic();
 292 
 293         /**
 294          * Returns whether or not this is a transitive dependency.
 295          * @return whether or not this is a transitive dependency
 296          */
 297         boolean isTransitive();
 298 
 299         /**
 300          * Returns the module that is required
 301          * @return the module that is required
 302          */
 303         ModuleElement getDependency();
 304     }
 305 
 306     /**
 307      * An exported package of a module.
 308      * @since 9
 309      * @spec JPMS
 310      */
 311     interface ExportsDirective extends Directive {
 312 
 313         /**
 314          * Returns the package being exported.
 315          * @return the package being exported
 316          */
 317         PackageElement getPackage();
 318 
 319         /**
 320          * Returns the specific modules to which the package is being exported,
 321          * or null, if the package is exported to all modules which
 322          * have readability to this module.
 323          * @return the specific modules to which the package is being exported
 324          */
 325         List<? extends ModuleElement> getTargetModules();
 326     }
 327 
 328     /**
 329      * An opened package of a module.
 330      * @since 9
 331      * @spec JPMS
 332      */
 333     interface OpensDirective extends Directive {
 334 
 335         /**
 336          * Returns the package being opened.
 337          * @return the package being opened
 338          */
 339         PackageElement getPackage();
 340 
 341         /**
 342          * Returns the specific modules to which the package is being open
 343          * or null, if the package is open all modules which
 344          * have readability to this module.
 345          * @return the specific modules to which the package is being opened
 346          */
 347         List<? extends ModuleElement> getTargetModules();
 348     }
 349 
 350     /**
 351      * An implementation of a service provided by a module.
 352      * @since 9
 353      * @spec JPMS
 354      */
 355     interface ProvidesDirective extends Directive {
 356         /**
 357          * Returns the service being provided.
 358          * @return the service being provided
 359          */
 360         TypeElement getService();
 361 
 362         /**
 363          * Returns the implementations of the service being provided.
 364          * @return the implementations of the service being provided
 365          */
 366         List<? extends TypeElement> getImplementations();
 367     }
 368 
 369     /**
 370      * A reference to a service used by a module.
 371      * @since 9
 372      * @spec JPMS
 373      */
 374     interface UsesDirective extends Directive {
 375         /**
 376          * Returns the service that is used.
 377          * @return the service that is used
 378          */
 379         TypeElement getService();
 380     }
 381 }