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