1 /*
   2  * Copyright (c) 2005, 2019, 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          *
 165          * @return the kind of this directive
 166          */
 167         DirectiveKind getKind();
 168 
 169         /**
 170          * Applies a visitor to this directive.
 171          *
 172          * @param <R> the return type of the visitor's methods
 173          * @param <P> the type of the additional parameter to the visitor's methods
 174          * @param v   the visitor operating on this directive
 175          * @param p   additional parameter to the visitor
 176          * @return a visitor-specified result
 177          */
 178         <R, P> R accept(DirectiveVisitor<R, P> v, P p);
 179     }
 180 
 181     /**
 182      * A visitor of module directives, in the style of the visitor design
 183      * pattern.  Classes implementing this interface are used to operate
 184      * on a directive when the kind of directive is unknown at compile time.
 185      * When a visitor is passed to a directive's {@link Directive#accept
 186      * accept} method, the <code>visit<i>Xyz</i></code> method applicable
 187      * to that directive is invoked.
 188      *
 189      * <p> Classes implementing this interface may or may not throw a
 190      * {@code NullPointerException} if the additional parameter {@code p}
 191      * is {@code null}; see documentation of the implementing class for
 192      * details.
 193      *
 194      * <p> <b>WARNING:</b> It is possible that methods will be added to
 195      * this interface to accommodate new, currently unknown, language
 196      * structures added to future versions of the Java&trade; programming
 197      * language. Methods to accommodate new language constructs will
 198      * be added in a source <em>compatible</em> way using
 199      * <em>default methods</em>.
 200      *
 201      * @param <R> the return type of this visitor's methods.  Use {@link
 202      *            Void} for visitors that do not need to return results.
 203      * @param <P> the type of the additional parameter to this visitor's
 204      *            methods.  Use {@code Void} for visitors that do not need an
 205      *            additional parameter.
 206      *
 207      * @since 9
 208      * @spec JPMS
 209      */
 210     interface DirectiveVisitor<R, P> {
 211         /**
 212          * Visits any directive as if by passing itself to that
 213          * directive's {@link Directive#accept accept} method and passing
 214          * {@code null} for the additional parameter.
 215          *
 216          * @param d  the directive to visit
 217          * @return a visitor-specified result
 218          * @implSpec The default implementation is {@code d.accept(v, null)}.
 219          */
 220         default R visit(Directive d) {
 221             return d.accept(this, null);
 222         }
 223 
 224         /**
 225          * Visits any directive as if by passing itself to that
 226          * directive's {@link Directive#accept accept} method.
 227          *
 228          * @param d  the directive to visit
 229          * @param p  a visitor-specified parameter
 230          * @return a visitor-specified result
 231          * @implSpec The default implementation is {@code d.accept(v, p)}.
 232          */
 233         default R visit(Directive d, P p) {
 234             return d.accept(this, p);
 235         }
 236 
 237         /**
 238          * Visits a {@code requires} directive.
 239          * @param d  the directive to visit
 240          * @param p  a visitor-specified parameter
 241          * @return a visitor-specified result
 242          */
 243         R visitRequires(RequiresDirective d, P p);
 244 
 245         /**
 246          * Visits an {@code exports} directive.
 247          * @param d  the directive to visit
 248          * @param p  a visitor-specified parameter
 249          * @return a visitor-specified result
 250          */
 251         R visitExports(ExportsDirective d, P p);
 252 
 253         /**
 254          * Visits an {@code opens} directive.
 255          * @param d  the directive to visit
 256          * @param p  a visitor-specified parameter
 257          * @return a visitor-specified result
 258          */
 259         R visitOpens(OpensDirective d, P p);
 260 
 261         /**
 262          * Visits a {@code uses} directive.
 263          * @param d  the directive to visit
 264          * @param p  a visitor-specified parameter
 265          * @return a visitor-specified result
 266          */
 267         R visitUses(UsesDirective d, P p);
 268 
 269         /**
 270          * Visits a {@code provides} directive.
 271          * @param d  the directive to visit
 272          * @param p  a visitor-specified parameter
 273          * @return a visitor-specified result
 274          */
 275         R visitProvides(ProvidesDirective d, P p);
 276 
 277         /**
 278          * Visits an unknown directive.
 279          * This can occur if the language evolves and new kinds of directive are added.
 280          * @param d  the directive to visit
 281          * @param p  a visitor-specified parameter
 282          * @return a visitor-specified result
 283          * @throws UnknownDirectiveException a visitor implementation may optionally throw this exception
 284          * @implSpec The default implementation throws {@code new UnknownDirectiveException(d, p)}.
 285          */
 286         default R visitUnknown(Directive d, P p) {
 287             throw new UnknownDirectiveException(d, p);
 288         }
 289     }
 290 
 291     /**
 292      * A dependency of a module.
 293      * @since 9
 294      * @spec JPMS
 295      */
 296     interface RequiresDirective extends Directive {
 297         /**
 298          * Returns whether or not this is a static dependency.
 299          * @return whether or not this is a static dependency
 300          */
 301         boolean isStatic();
 302 
 303         /**
 304          * Returns whether or not this is a transitive dependency.
 305          * @return whether or not this is a transitive dependency
 306          */
 307         boolean isTransitive();
 308 
 309         /**
 310          * Returns the module that is required
 311          * @return the module that is required
 312          */
 313         ModuleElement getDependency();
 314     }
 315 
 316     /**
 317      * An exported package of a module.
 318      * @since 9
 319      * @spec JPMS
 320      */
 321     interface ExportsDirective extends Directive {
 322 
 323         /**
 324          * Returns the package being exported.
 325          * @return the package being exported
 326          */
 327         PackageElement getPackage();
 328 
 329         /**
 330          * Returns the specific modules to which the package is being exported,
 331          * or {@code null}, if the package is exported to all modules which
 332          * have readability to this module.
 333          * @return the specific modules to which the package is being exported
 334          */
 335         List<? extends ModuleElement> getTargetModules();
 336     }
 337 
 338     /**
 339      * An opened package of a module.
 340      * @since 9
 341      * @spec JPMS
 342      */
 343     interface OpensDirective extends Directive {
 344 
 345         /**
 346          * Returns the package being opened.
 347          * @return the package being opened
 348          */
 349         PackageElement getPackage();
 350 
 351         /**
 352          * Returns the specific modules to which the package is being open
 353          * or {@code null}, if the package is open all modules which
 354          * have readability to this module.
 355          * @return the specific modules to which the package is being opened
 356          */
 357         List<? extends ModuleElement> getTargetModules();
 358     }
 359 
 360     /**
 361      * An implementation of a service provided by a module.
 362      * @since 9
 363      * @spec JPMS
 364      */
 365     interface ProvidesDirective extends Directive {
 366         /**
 367          * Returns the service being provided.
 368          * @return the service being provided
 369          */
 370         TypeElement getService();
 371 
 372         /**
 373          * Returns the implementations of the service being provided.
 374          * @return the implementations of the service being provided
 375          */
 376         List<? extends TypeElement> getImplementations();
 377     }
 378 
 379     /**
 380      * A reference to a service used by a module.
 381      * @since 9
 382      * @spec JPMS
 383      */
 384     interface UsesDirective extends Directive {
 385         /**
 386          * Returns the service that is used.
 387          * @return the service that is used
 388          */
 389         TypeElement getService();
 390     }
 391 }