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