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