Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8306730

Add nominal descriptors of modules and packages to Constants API

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P4 P4
    • 21
    • core-libs
    • None
    • source
    • minimal
    • Adding new sealed interfaces to `java.lang.constant` package represents minimal compatibility risk.
    • Java API
    • SE

      Summary

      Add nominal descriptors for module and package constants to Constants API.

      Problem

      Every Java class file has a constant pool, JVMS 20 4.4, which stores the operands for bytecode instructions in the class. Constants API already provides models for all loadable constants to help programs manipulating class files and modelling bytecode instructions.

      However no models of module and package constants are provided by Constants API. Every program manipulating class files must implement own models and validation of modules and packages constants.

      Solution

      Add java.lang.constant.ModuleDesc and java.lang.constant.PackageDesc.

      Specification

      java.lang.constant.ModuleDesc:

      package java.lang.constant;
      
      import static java.util.Objects.requireNonNull;
      
      /**
       * A nominal descriptor for a {@code Module} constant.
       *
       * <p>
       * To create a {@link ModuleDesc} for a module, use the {@link #of(String)}
       * method.
       *
       * @jvms 4.4.11 The CONSTANT_Module_info Structure
       * @since 21
       */
      public sealed interface ModuleDesc
              permits ModuleDescImpl {
      
          /**
           * Returns a {@link ModuleDesc} for a module,
           * given the name of the module.
           *
           * @param name the module name
           * @return a {@link ModuleDesc} describing the desired module
           * @throws NullPointerException if the argument is {@code null}
           * @throws IllegalArgumentException if the name string is not in the
           * correct format
           * @jvms 4.2.3 Module and Package Names
           */
          static ModuleDesc of(String name) {
              ConstantUtils.validateModuleName(requireNonNull(name));
              return new ModuleDescImpl(name);
          }
      
          /**
           * Returns the module name of this {@link ModuleDesc}.
           *
           * @return the module name
           */
          String name();
      
          /**
           * Compare the specified object with this descriptor for equality.
           * Returns {@code true} if and only if the specified object is
           * also a {@link ModuleDesc} and both describe the same module.
           *
           * @param o the other object
           * @return whether this descriptor is equal to the other object
           */
          @Override
          boolean equals(Object o);
      }

      java.lang.constant.PackageDesc:

      package java.lang.constant;
      
      import static java.util.Objects.requireNonNull;
      
      /**
       * A nominal descriptor for a {@code Package} constant.
       *
       * <p>
       * To create a {@link PackageDesc} for a package,
       * use the {@link #of(String)} or {@link #ofInternalName(String)} method.
       *
       * @jvms 4.4.12 The CONSTANT_Package_info Structure
       * @since 21
       */
      public sealed interface PackageDesc
              permits PackageDescImpl {
      
          /**
           * Returns a {@link PackageDesc} for a package,
           * given the name of the package, such as {@code "java.lang"}.
           *
           * @param name the fully qualified (dot-separated) package name
           * @return a {@link PackageDesc} describing the desired package
           * @throws NullPointerException if the argument is {@code null}
           * @throws IllegalArgumentException if the name string is not in the
           * correct format
           * @jls 6.7 Fully Qualified Names and Canonical Names
           * @see PackageDesc#ofInternalName(String)
           */
          static PackageDesc of(String name) {
              ConstantUtils.validateBinaryPackageName(requireNonNull(name));
              return new PackageDescImpl(ConstantUtils.binaryToInternal(name));
          }
      
          /**
           * Returns a {@link PackageDesc} for a package,
           * given the name of the package in internal form,
           * such as {@code "java/lang"}.
           *
           * @param name the fully qualified package name, in internal
           * (slash-separated) form
           * @return a {@link PackageDesc} describing the desired package
           * @throws NullPointerException if the argument is {@code null}
           * @throws IllegalArgumentException if the name string is not in the
           * correct format
           * @jvms 4.2.1 Binary Class and Interface Names
           * @jvms 4.2.3 Module and Package Names
           * @see PackageDesc#of(String)
           */
          static PackageDesc ofInternalName(String name) {
              ConstantUtils.validateInternalPackageName(requireNonNull(name));
              return new PackageDescImpl(name);
          }
      
          /**
           * Returns the fully qualified (slash-separated) internal package name
           * of this {@link PackageDesc}.
           *
           * @return the package name, or the empty string for the
           * unnamed package
           * @see PackageDesc#name()
           */
          String internalName();
      
          /**
           * Returns the fully qualified (dot-separated) binary package name
           * of this {@link PackageDesc}.
           *
           * @return the package name, or the empty string for the
           * unnamed package
           * @see PackageDesc#internalName()
           */
          default String name() {
              return ConstantUtils.internalToBinary(internalName());
          }
      
          /**
           * Compare the specified object with this descriptor for equality.
           * Returns {@code true} if and only if the specified object is
           * also a {@link PackageDesc} and both describe the same package.
           *
           * @param o the other object
           * @return whether this descriptor is equal to the other object
           */
          @Override
          boolean equals(Object o);
      }

      Added paragraph to java.lang.constant.package-info:

       * <p>Other members of this package are {@link java.lang.constant.ModuleDesc}
       * and  {@link java.lang.constant.PackageDesc}. They represent module and package
       * info structures, suitable for describing modules and their content in bytecode
       * reading and writing APIs.

            asotona Adam Sotona
            asotona Adam Sotona
            Mandy Chung (Inactive)
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: