make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java
changeset 51832 bf1d479fe7eb
parent 51799 3fabe59fe4de
child 53696 f0f8f0afed74
equal deleted inserted replaced
51831:ec03768578c2 51832:bf1d479fe7eb
   207     //<editor-fold defaultstate="collapsed" desc="ct.sym construction">
   207     //<editor-fold defaultstate="collapsed" desc="ct.sym construction">
   208     /**Create sig files for ct.sym reading the classes description from the directory that contains
   208     /**Create sig files for ct.sym reading the classes description from the directory that contains
   209      * {@code ctDescriptionFile}, using the file as a recipe to create the sigfiles.
   209      * {@code ctDescriptionFile}, using the file as a recipe to create the sigfiles.
   210      */
   210      */
   211     @SuppressWarnings("unchecked")
   211     @SuppressWarnings("unchecked")
   212     public void createSymbols(String ctDescriptionFileExtra, String ctDescriptionFile, String ctSymLocation, CtSymKind ctSymKind) throws IOException {
   212     public void createSymbols(String ctDescriptionFileExtra, String ctDescriptionFile, String ctSymLocation) throws IOException {
   213         LoadDescriptions data = load(ctDescriptionFileExtra != null ? Paths.get(ctDescriptionFileExtra)
   213         LoadDescriptions data = load(ctDescriptionFileExtra != null ? Paths.get(ctDescriptionFileExtra)
   214                                                                     : null,
   214                                                                     : null,
   215                                      Paths.get(ctDescriptionFile), null);
   215                                      Paths.get(ctDescriptionFile), null);
   216 
   216 
   217         splitHeaders(data.classes);
   217         splitHeaders(data.classes);
       
   218 
       
   219         Map<String, Map<Character, String>> package2Version2Module = new HashMap<>();
   218 
   220 
   219         for (ModuleDescription md : data.modules.values()) {
   221         for (ModuleDescription md : data.modules.values()) {
   220             for (ModuleHeaderDescription mhd : md.header) {
   222             for (ModuleHeaderDescription mhd : md.header) {
   221                 List<String> versionsList =
   223                 List<String> versionsList =
   222                         Collections.singletonList(mhd.versions);
   224                         Collections.singletonList(mhd.versions);
   223                 writeModulesForVersions(ctSymLocation,
   225                 writeModulesForVersions(ctSymLocation,
   224                                         md,
   226                                         md,
   225                                         mhd,
   227                                         mhd,
   226                                         versionsList);
   228                                         versionsList);
       
   229                 mhd.exports.stream().forEach(pkg -> {
       
   230                     for (char v : mhd.versions.toCharArray()) {
       
   231                         package2Version2Module.computeIfAbsent(pkg, dummy -> new HashMap<>()).put(v, md.name);
       
   232                     }
       
   233                 });
   227             }
   234             }
   228         }
   235         }
   229 
   236 
   230         for (ClassDescription classDescription : data.classes) {
   237         for (ClassDescription classDescription : data.classes) {
       
   238             Map<Character, String> version2Module = package2Version2Module.getOrDefault(classDescription.packge().replace('.', '/'), Collections.emptyMap());
   231             for (ClassHeaderDescription header : classDescription.header) {
   239             for (ClassHeaderDescription header : classDescription.header) {
   232                 switch (ctSymKind) {
   240                 Set<String> jointVersions = new HashSet<>();
   233                     case JOINED_VERSIONS:
   241                 jointVersions.add(header.versions);
   234                         Set<String> jointVersions = new HashSet<>();
   242                 limitJointVersion(jointVersions, classDescription.fields);
   235                         jointVersions.add(header.versions);
   243                 limitJointVersion(jointVersions, classDescription.methods);
   236                         limitJointVersion(jointVersions, classDescription.fields);
   244                 Map<String, StringBuilder> module2Versions = new HashMap<>();
   237                         limitJointVersion(jointVersions, classDescription.methods);
   245                 for (char v : header.versions.toCharArray()) {
   238                         writeClassesForVersions(ctSymLocation, classDescription, header, jointVersions);
   246                     String module = version2Module.get(v);
   239                         break;
   247                     if (module == null) {
   240                     case SEPARATE:
   248                         if (v >= '9') {
   241                         Set<String> versions = new HashSet<>();
   249                             throw new AssertionError("No module for " + classDescription.name +
   242                         for (char v : header.versions.toCharArray()) {
   250                                                      " and version " + v);
   243                             versions.add("" + v);
       
   244                         }
   251                         }
   245                         writeClassesForVersions(ctSymLocation, classDescription, header, versions);
   252                         module = version2Module.get('9');
   246                         break;
   253                         if (module == null) {
       
   254                             module = "java.base";
       
   255                         }
       
   256                     }
       
   257                     module2Versions.computeIfAbsent(module, dummy -> new StringBuilder()).append(v);
       
   258                 }
       
   259                 for (Entry<String, StringBuilder> e : module2Versions.entrySet()) {
       
   260                     Set<String> currentVersions = new HashSet<>(jointVersions);
       
   261                     limitJointVersion(currentVersions, e.getValue().toString());
       
   262                     currentVersions = currentVersions.stream().filter(vers -> !disjoint(vers, e.getValue().toString())).collect(Collectors.toSet());
       
   263                     writeClassesForVersions(ctSymLocation, classDescription, header, e.getKey(), currentVersions);
   247                 }
   264                 }
   248             }
   265             }
   249         }
   266         }
   250     }
   267     }
   251 
   268 
   589                     newHeader.flags = header.flags;
   606                     newHeader.flags = header.flags;
   590                     newHeader.implementsAttr = header.implementsAttr;
   607                     newHeader.implementsAttr = header.implementsAttr;
   591                     newHeader.innerClasses = header.innerClasses;
   608                     newHeader.innerClasses = header.innerClasses;
   592                     newHeader.runtimeAnnotations = header.runtimeAnnotations;
   609                     newHeader.runtimeAnnotations = header.runtimeAnnotations;
   593                     newHeader.signature = header.signature;
   610                     newHeader.signature = header.signature;
   594                     newHeader.versions = reduce(versions, header.versions);
   611                     newHeader.versions = reduce(header.versions, versions);
   595 
   612 
   596                     newHeaders.add(newHeader);
   613                     newHeaders.add(newHeader);
   597                 }
   614                 }
   598             }
   615             }
   599 
   616 
   601         }
   618         }
   602     }
   619     }
   603 
   620 
   604     void limitJointVersion(Set<String> jointVersions, List<? extends FeatureDescription> features) {
   621     void limitJointVersion(Set<String> jointVersions, List<? extends FeatureDescription> features) {
   605         for (FeatureDescription feature : features) {
   622         for (FeatureDescription feature : features) {
   606             for (String version : jointVersions) {
   623             limitJointVersion(jointVersions, feature.versions);
   607                 if (!containsAll(feature.versions, version) &&
   624         }
   608                     !disjoint(feature.versions, version)) {
   625     }
   609                     StringBuilder featurePart = new StringBuilder();
   626 
   610                     StringBuilder otherPart = new StringBuilder();
   627     void limitJointVersion(Set<String> jointVersions, String versions) {
   611                     for (char v : version.toCharArray()) {
   628         for (String version : jointVersions) {
   612                         if (feature.versions.indexOf(v) != (-1)) {
   629             if (!containsAll(versions, version) &&
   613                             featurePart.append(v);
   630                 !disjoint(versions, version)) {
   614                         } else {
   631                 StringBuilder featurePart = new StringBuilder();
   615                             otherPart.append(v);
   632                 StringBuilder otherPart = new StringBuilder();
   616                         }
   633                 for (char v : version.toCharArray()) {
       
   634                     if (versions.indexOf(v) != (-1)) {
       
   635                         featurePart.append(v);
       
   636                     } else {
       
   637                         otherPart.append(v);
   617                     }
   638                     }
   618                     jointVersions.remove(version);
   639                 }
   619                     if (featurePart.length() == 0 || otherPart.length() == 0) {
   640                 jointVersions.remove(version);
   620                         throw new AssertionError();
   641                 if (featurePart.length() == 0 || otherPart.length() == 0) {
   621                     }
   642                     throw new AssertionError();
   622                     jointVersions.add(featurePart.toString());
   643                 }
   623                     jointVersions.add(otherPart.toString());
   644                 jointVersions.add(featurePart.toString());
   624                     break;
   645                 jointVersions.add(otherPart.toString());
   625                 }
   646                 break;
   626             }
   647             }
   627         }
   648         }
   628     }
   649     }
   629 
   650 
   630     private static boolean containsAll(String versions, String subVersions) {
   651     private static boolean containsAll(String versions, String subVersions) {
   644     }
   665     }
   645 
   666 
   646     void writeClassesForVersions(String ctSymLocation,
   667     void writeClassesForVersions(String ctSymLocation,
   647                                  ClassDescription classDescription,
   668                                  ClassDescription classDescription,
   648                                  ClassHeaderDescription header,
   669                                  ClassHeaderDescription header,
       
   670                                  String module,
   649                                  Iterable<String> versions)
   671                                  Iterable<String> versions)
   650             throws IOException {
   672             throws IOException {
   651         for (String ver : versions) {
   673         for (String ver : versions) {
   652             writeClass(ctSymLocation, classDescription, header, ver);
   674             writeClass(ctSymLocation, classDescription, header, module, ver);
   653         }
   675         }
   654     }
   676     }
   655 
   677 
   656     void writeModulesForVersions(String ctSymLocation,
   678     void writeModulesForVersions(String ctSymLocation,
   657                                  ModuleDescription moduleDescription,
   679                                  ModuleDescription moduleDescription,
   659                                  Iterable<String> versions)
   681                                  Iterable<String> versions)
   660             throws IOException {
   682             throws IOException {
   661         for (String ver : versions) {
   683         for (String ver : versions) {
   662             writeModule(ctSymLocation, moduleDescription, header, ver);
   684             writeModule(ctSymLocation, moduleDescription, header, ver);
   663         }
   685         }
   664     }
       
   665 
       
   666     public enum CtSymKind {
       
   667         JOINED_VERSIONS,
       
   668         SEPARATE;
       
   669     }
   686     }
   670 
   687 
   671     //<editor-fold defaultstate="collapsed" desc="Class Writing">
   688     //<editor-fold defaultstate="collapsed" desc="Class Writing">
   672     void writeModule(String ctSymLocation,
   689     void writeModule(String ctSymLocation,
   673                     ModuleDescription moduleDescription,
   690                     ModuleDescription moduleDescription,
   695                 new Field[0],
   712                 new Field[0],
   696                 new Method[0],
   713                 new Method[0],
   697                 attributes);
   714                 attributes);
   698 
   715 
   699         Path outputClassFile = Paths.get(ctSymLocation,
   716         Path outputClassFile = Paths.get(ctSymLocation,
   700                                          version + "-modules",
   717                                          version,
   701                                          moduleDescription.name,
   718                                          moduleDescription.name,
   702                                          "module-info" + EXTENSION);
   719                                          "module-info" + EXTENSION);
   703 
   720 
   704         Files.createDirectories(outputClassFile.getParent());
   721         Files.createDirectories(outputClassFile.getParent());
   705 
   722 
   711     }
   728     }
   712 
   729 
   713     void writeClass(String ctSymLocation,
   730     void writeClass(String ctSymLocation,
   714                     ClassDescription classDescription,
   731                     ClassDescription classDescription,
   715                     ClassHeaderDescription header,
   732                     ClassHeaderDescription header,
       
   733                     String module,
   716                     String version) throws IOException {
   734                     String version) throws IOException {
   717         List<CPInfo> constantPool = new ArrayList<>();
   735         List<CPInfo> constantPool = new ArrayList<>();
   718         constantPool.add(null);
   736         constantPool.add(null);
   719         List<Method> methods = new ArrayList<>();
   737         List<Method> methods = new ArrayList<>();
   720         for (MethodDescription methDesc : classDescription.methods) {
   738         for (MethodDescription methDesc : classDescription.methods) {
   763                 interfaces,
   781                 interfaces,
   764                 fields.toArray(new Field[0]),
   782                 fields.toArray(new Field[0]),
   765                 methods.toArray(new Method[0]),
   783                 methods.toArray(new Method[0]),
   766                 attributes);
   784                 attributes);
   767 
   785 
   768         Path outputClassFile = Paths.get(ctSymLocation, version, classDescription.name + EXTENSION);
   786         Path outputClassFile = Paths.get(ctSymLocation, version);
       
   787 
       
   788         if (module != null) {
       
   789             outputClassFile = outputClassFile.resolve(module);
       
   790         }
       
   791 
       
   792         outputClassFile = outputClassFile.resolve(classDescription.name + EXTENSION);
   769 
   793 
   770         Files.createDirectories(outputClassFile.getParent());
   794         Files.createDirectories(outputClassFile.getParent());
   771 
   795 
   772         try (OutputStream out = Files.newOutputStream(outputClassFile)) {
   796         try (OutputStream out = Files.newOutputStream(outputClassFile)) {
   773             ClassWriter w = new ClassWriter();
   797             ClassWriter w = new ClassWriter();
  3650                     return ;
  3674                     return ;
  3651                 }
  3675                 }
  3652 
  3676 
  3653                 new CreateSymbols().createSymbols(ctDescriptionFileExtra,
  3677                 new CreateSymbols().createSymbols(ctDescriptionFileExtra,
  3654                                                   ctDescriptionFile,
  3678                                                   ctDescriptionFile,
  3655                                                   ctSymLocation,
  3679                                                   ctSymLocation);
  3656                                                   CtSymKind.JOINED_VERSIONS);
       
  3657                 break;
  3680                 break;
  3658         }
  3681         }
  3659     }
  3682     }
  3660 
  3683 
  3661 }
  3684 }