1 /*
   2  * Copyright (c) 2015, 2016, 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 jdk.nashorn.internal.ir;
  27 
  28 import java.util.List;
  29 
  30 /**
  31  * ES6 Module information.
  32  */
  33 public final class Module {
  34 
  35     /** The synthetic binding name assigned to export default declarations with unnamed expressions. */
  36     public static final String DEFAULT_EXPORT_BINDING_NAME = "*default*";
  37 
  38     /** The {@code export default} name. */
  39     public static final String DEFAULT_NAME = "default";
  40 
  41     /** The {@code export *} name. */
  42     public static final String STAR_NAME = "*";
  43 
  44     /**
  45      * A module ExportEntry record.
  46      *
  47      * @see <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-source-text-module-records">es6 modules</a>
  48      */
  49     public static final class ExportEntry {
  50         private final IdentNode exportName;
  51         private final IdentNode moduleRequest;
  52         private final IdentNode importName;
  53         private final IdentNode localName;
  54 
  55         private final int startPosition;
  56         private final int endPosition;
  57 
  58         private ExportEntry(final IdentNode exportName, final IdentNode moduleRequest, final IdentNode importName,
  59                             final IdentNode localName, final int startPosition, final int endPosition) {
  60             this.exportName = exportName;
  61             this.moduleRequest = moduleRequest;
  62             this.importName = importName;
  63             this.localName = localName;
  64             this.startPosition = startPosition;
  65             this.endPosition = endPosition;
  66         }
  67 
  68         /**
  69          * Creates a {@code export *} export entry.
  70          *
  71          * @param starName the star name
  72          * @param moduleRequest the module request
  73          * @param startPosition the start position
  74          * @param endPosition the end position
  75          * @return the export entry
  76          */
  77         public static ExportEntry exportStarFrom(final IdentNode starName, final IdentNode moduleRequest, final int startPosition, final int endPosition) {
  78             return new ExportEntry(null, moduleRequest, starName, null, startPosition, endPosition);
  79         }
  80 
  81         /**
  82          * Creates a {@code export default} export entry with a local name.
  83          *
  84          * @param defaultName the default name
  85          * @param localName the local name
  86          * @param startPosition the start position
  87          * @param endPosition the end position
  88          * @return the export entry
  89          */
  90         public static ExportEntry exportDefault(final IdentNode defaultName, final IdentNode localName, final int startPosition, final int endPosition) {
  91             return new ExportEntry(defaultName, null, null, localName, startPosition, endPosition);
  92         }
  93 
  94         /**
  95          * Creates a export entry with a local name and export name.
  96          *
  97          * @param exportName the export name
  98          * @param localName the local name
  99          * @param startPosition the start position
 100          * @param endPosition the end position
 101          * @return the export entry
 102          */
 103         public static ExportEntry exportSpecifier(final IdentNode exportName, final IdentNode localName, final int startPosition, final int endPosition) {
 104             return new ExportEntry(exportName, null, null, localName, startPosition, endPosition);
 105         }
 106 
 107 
 108         /**
 109          * Creates a export entry with an export name.
 110          *
 111          * @param exportName the export name
 112          * @param startPosition the start position
 113          * @param endPosition the end position
 114          * @return the export entry
 115          */
 116         public static ExportEntry exportSpecifier(final IdentNode exportName, final int startPosition, final int endPosition) {
 117             return exportSpecifier(exportName, exportName, startPosition, endPosition);
 118         }
 119 
 120         /**
 121          * Create a copy of this entry with the specified {@code module request} string.
 122          *
 123          * @param moduleRequest the module request
 124          * @param endPosition the new endPosition
 125          * @return the new export entry
 126          */
 127         public ExportEntry withFrom(@SuppressWarnings("hiding") final IdentNode moduleRequest, final int endPosition) {
 128             // Note that "from" moves localName to inputName, and localName becomes null
 129             return new ExportEntry(exportName, moduleRequest, localName, null, startPosition, endPosition);
 130         }
 131 
 132         /**
 133          * Returns the entry's export name.
 134          *
 135          * @return the export name
 136          */
 137         public IdentNode getExportName() {
 138             return exportName;
 139         }
 140 
 141         /**
 142          * Returns the entry's module request.
 143          *
 144          * @return the module request
 145          */
 146         public IdentNode getModuleRequest() {
 147             return moduleRequest;
 148         }
 149 
 150         /**
 151          * Returns the entry's import name.
 152          *
 153          * @return the import name
 154          */
 155         public IdentNode getImportName() {
 156             return importName;
 157         }
 158 
 159         /**
 160          * Returns the entry's local name.
 161          *
 162          * @return the local name
 163          */
 164         public IdentNode getLocalName() {
 165             return localName;
 166         }
 167 
 168         /**
 169          * Returns the entry's start position.
 170          *
 171          * @return the start position
 172          */
 173         public int getStartPosition() {
 174             return startPosition;
 175         }
 176 
 177         /**
 178          * Returns the entry's end position.
 179          *
 180          * @return the end position
 181          */
 182         public int getEndPosition() {
 183             return endPosition;
 184         }
 185 
 186         @Override
 187         public String toString() {
 188             return "ExportEntry [exportName=" + exportName + ", moduleRequest=" + moduleRequest + ", importName=" + importName + ", localName=" + localName + "]";
 189         }
 190     }
 191 
 192     /**
 193      * An ImportEntry record.
 194      *
 195      * @see <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-source-text-module-records">es6 modules</a>
 196      */
 197     public static final class ImportEntry {
 198         private final IdentNode moduleRequest;
 199         private final IdentNode importName;
 200         private final IdentNode localName;
 201 
 202         private final int startPosition;
 203         private final int endPosition;
 204 
 205         private ImportEntry(final IdentNode moduleRequest, final IdentNode importName, final IdentNode localName,
 206                             final int startPosition, final int endPosition) {
 207             this.moduleRequest = moduleRequest;
 208             this.importName = importName;
 209             this.localName = localName;
 210             this.startPosition = startPosition;
 211             this.endPosition = endPosition;
 212         }
 213 
 214         /**
 215          * Creates an import entry with the given import and local names.
 216          *
 217          * @param importName the import name
 218          * @param localName the local name
 219          * @param startPosition the start position
 220          * @param endPosition the end position
 221          * @return the import entry
 222          */
 223         public static ImportEntry importSpecifier(final IdentNode importName, final IdentNode localName, final int startPosition, final int endPosition) {
 224             return new ImportEntry(null, importName, localName, startPosition, endPosition);
 225         }
 226 
 227         /**
 228          * Creates a new import entry with the given import name.
 229          *
 230          * @param importName the import name
 231          * @param startPosition the start position
 232          * @param endPosition the end position
 233          * @return the import entry
 234          */
 235         public static ImportEntry importSpecifier(final IdentNode importName, final int startPosition, final int endPosition) {
 236             return importSpecifier(importName, importName, startPosition, endPosition);
 237         }
 238 
 239         /**
 240          * Returns a copy of this import entry with the given module request and end position.
 241          *
 242          * @param moduleRequest the module request
 243          * @param endPosition the new end position
 244          * @return the new import entry
 245          */
 246         public ImportEntry withFrom(@SuppressWarnings("hiding") final IdentNode moduleRequest, final int endPosition) {
 247             return new ImportEntry(moduleRequest, importName, localName, startPosition, endPosition);
 248         }
 249 
 250         /**
 251          * Returns the entry's module request.
 252          *
 253          * @return the module request
 254          */
 255         public IdentNode getModuleRequest() {
 256             return moduleRequest;
 257         }
 258 
 259         /**
 260          * Returns the entry's import name.
 261          *
 262          * @return the import name
 263          */
 264         public IdentNode getImportName() {
 265             return importName;
 266         }
 267 
 268         /**
 269          * Returns the entry's local name.
 270          *
 271          * @return the local name
 272          */
 273         public IdentNode getLocalName() {
 274             return localName;
 275         }
 276 
 277         /**
 278          * Returns the entry's start position.
 279          *
 280          * @return the start position
 281          */
 282         public int getStartPosition() {
 283             return startPosition;
 284         }
 285 
 286         /**
 287          * Returns the entry's end position.
 288          *
 289          * @return the end position
 290          */
 291         public int getEndPosition() {
 292             return endPosition;
 293         }
 294 
 295         @Override
 296         public String toString() {
 297             return "ImportEntry [moduleRequest=" + moduleRequest + ", importName=" + importName + ", localName=" + localName + "]";
 298         }
 299     }
 300 
 301     private final List<String> requestedModules;
 302     private final List<ImportEntry> importEntries;
 303     private final List<ExportEntry> localExportEntries;
 304     private final List<ExportEntry> indirectExportEntries;
 305     private final List<ExportEntry> starExportEntries;
 306 
 307     /**
 308      * Creates a module with the specified requested modules and import and export entries.
 309      *
 310      * @param requestedModules the requested modules
 311      * @param importEntries the import entries
 312      * @param localExportEntries local export entries
 313      * @param indirectExportEntries indirect export entries
 314      * @param starExportEntries star export entries
 315      */
 316     public Module(final List<String> requestedModules, final List<ImportEntry> importEntries, final List<ExportEntry> localExportEntries,
 317                   final List<ExportEntry> indirectExportEntries, final List<ExportEntry> starExportEntries) {
 318         this.requestedModules = requestedModules;
 319         this.importEntries = importEntries;
 320         this.localExportEntries = localExportEntries;
 321         this.indirectExportEntries = indirectExportEntries;
 322         this.starExportEntries = starExportEntries;
 323     }
 324 
 325     /**
 326      * Returns the list of requested modules.
 327      *
 328      * @return the requested modules
 329      */
 330     public List<String> getRequestedModules() {
 331         return requestedModules;
 332     }
 333 
 334     /**
 335      * Returns the list of import entries.
 336      *
 337      * @return the import entries
 338      */
 339     public List<ImportEntry> getImportEntries() {
 340         return importEntries;
 341     }
 342 
 343     /**
 344      * Returns the list of local export entries.
 345      *
 346      * @return the local export entries
 347      */
 348     public List<ExportEntry> getLocalExportEntries() {
 349         return localExportEntries;
 350     }
 351 
 352     /**
 353      * Returns the list of indirect export entries.
 354      *
 355      * @return the indirect export entries
 356      */
 357     public List<ExportEntry> getIndirectExportEntries() {
 358         return indirectExportEntries;
 359     }
 360 
 361     /**
 362      * Returns the list of star export entries.
 363      *
 364      * @return the star export entries
 365      */
 366     public List<ExportEntry> getStarExportEntries() {
 367         return starExportEntries;
 368     }
 369 
 370     @Override
 371     public String toString() {
 372         return "Module [requestedModules=" + requestedModules + ", importEntries=" + importEntries + ", localExportEntries=" + localExportEntries + ", indirectExportEntries=" +
 373                 indirectExportEntries + ", starExportEntries=" + starExportEntries + "]";
 374     }
 375 }