1769 }
1770
1771 headerDesc.versions += version;
1772
1773 if (!existed) {
1774 moduleDesc.header.add(headerDesc);
1775 }
1776 }
1777
1778 private boolean include(int accessFlags) {
1779 return (accessFlags & (AccessFlags.ACC_PUBLIC | AccessFlags.ACC_PROTECTED)) != 0;
1780 }
1781
1782 private void addClassHeader(ClassDescription clazzDesc, ClassHeaderDescription headerDesc, String version) {
1783 //normalize:
1784 boolean existed = false;
1785 for (ClassHeaderDescription existing : clazzDesc.header) {
1786 if (existing.equals(headerDesc)) {
1787 headerDesc = existing;
1788 existed = true;
1789 } else {
1790 //check if the only difference between the 7 and 8 version is the Profile annotation
1791 //if so, copy it to the pre-8 version, so save space
1792 List<AnnotationDescription> annots = existing.classAnnotations;
1793
1794 if (annots != null) {
1795 for (AnnotationDescription ad : annots) {
1796 if (PROFILE_ANNOTATION.equals(ad.annotationType)) {
1797 existing.classAnnotations = new ArrayList<>(annots);
1798 existing.classAnnotations.remove(ad);
1799 if (existing.equals(headerDesc)) {
1800 headerDesc = existing;
1801 existed = true;
1802 }
1803 existing.classAnnotations = annots;
1804 break;
1805 }
1806 }
1807 }
1808 }
1809 }
1810
1811 headerDesc.versions += version;
2593 public static RequiresDescription deserialize(String data) {
2594 Map<String, String> attributes = splitAttributes(data);
2595
2596 Integer ver = attributes.containsKey("version")
2597 ? Integer.parseInt(attributes.get("version"))
2598 : null;
2599 int flags = Integer.parseInt(attributes.get("flags"), 16);
2600 return new RequiresDescription(attributes.get("name"),
2601 flags,
2602 ver);
2603 }
2604
2605 public static RequiresDescription create(ClassFile cf,
2606 RequiresEntry req) {
2607 String mod = getModuleName(cf, req.requires_index);
2608 Integer ver = getVersion(cf, req.requires_version_index);
2609 return new RequiresDescription(mod,
2610 req.requires_flags,
2611 ver);
2612 }
2613 }
2614
2615 static class ProvidesDescription {
2616 final String interfaceName;
2617 final List<String> implNames;
2618
2619 public ProvidesDescription(String interfaceName,
2620 List<String> implNames) {
2621 this.interfaceName = interfaceName;
2622 this.implNames = implNames;
2623 }
2624
2625 public String serialize() {
2626 return "interface " + quote(interfaceName, true) +
2627 " impls " + quote(serializeList(implNames), true, true);
2628 }
2629
2630 public static ProvidesDescription deserialize(String data) {
2631 Map<String, String> attributes = splitAttributes(data);
2632 List<String> implsList =
2633 deserializeList(attributes.get("impls"),
2634 false);
2635 return new ProvidesDescription(attributes.get("interface"),
2636 implsList);
2637 }
2638
2639 public static ProvidesDescription create(ClassFile cf,
2640 ProvidesEntry prov) {
2641 String api = getClassName(cf, prov.provides_index);
2642 List<String> impls =
2643 Arrays.stream(prov.with_index)
2644 .mapToObj(wi -> getClassName(cf, wi))
2645 .collect(Collectors.toList());
2646 return new ProvidesDescription(api, impls);
2647 }
2648 }
2649 }
2650
2651 public static class ClassDescription {
2652 String name;
2653 List<ClassHeaderDescription> header = new ArrayList<>();
2654 List<MethodDescription> methods = new ArrayList<>();
2655 List<FieldDescription> fields = new ArrayList<>();
2656
2657 public void write(Appendable output, String baselineVersion,
2658 String version) throws IOException {
2659 boolean inBaseline = false;
2660 boolean inVersion = false;
2661 for (ClassHeaderDescription chd : header) {
2662 if (baselineVersion != null &&
2663 chd.versions.contains(baselineVersion)) {
2664 inBaseline = true;
2665 }
2666 if (chd.versions.contains(version)) {
2667 inVersion = true;
2789 }
2790
2791 @Override
2792 public boolean equals(Object obj) {
2793 if (obj == null) {
2794 return false;
2795 }
2796 if (!super.equals(obj)) {
2797 return false;
2798 }
2799 final ClassHeaderDescription other = (ClassHeaderDescription) obj;
2800 if (!Objects.equals(this.extendsAttr, other.extendsAttr)) {
2801 return false;
2802 }
2803 if (!Objects.equals(this.implementsAttr, other.implementsAttr)) {
2804 return false;
2805 }
2806 if (!Objects.equals(this.nestHost, other.nestHost)) {
2807 return false;
2808 }
2809 if (!Objects.equals(this.nestMembers, other.nestMembers)) {
2810 return false;
2811 }
2812 return true;
2813 }
2814
2815 @Override
2816 public void write(Appendable output, String baselineVersion, String version) throws IOException {
2817 if (!versions.contains(version) ||
2818 (baselineVersion != null && versions.contains(baselineVersion) && versions.contains(version)))
2819 return ;
2820 output.append("header");
2821 if (extendsAttr != null)
2822 output.append(" extends " + extendsAttr);
2823 if (implementsAttr != null && !implementsAttr.isEmpty())
2824 output.append(" implements " + serializeList(implementsAttr));
2825 if (nestHost != null)
2826 output.append(" nestHost " + nestHost);
2827 if (nestMembers != null && !nestMembers.isEmpty())
2828 output.append(" nestMembers " + serializeList(nestMembers));
2829 writeAttributes(output);
|
1769 }
1770
1771 headerDesc.versions += version;
1772
1773 if (!existed) {
1774 moduleDesc.header.add(headerDesc);
1775 }
1776 }
1777
1778 private boolean include(int accessFlags) {
1779 return (accessFlags & (AccessFlags.ACC_PUBLIC | AccessFlags.ACC_PROTECTED)) != 0;
1780 }
1781
1782 private void addClassHeader(ClassDescription clazzDesc, ClassHeaderDescription headerDesc, String version) {
1783 //normalize:
1784 boolean existed = false;
1785 for (ClassHeaderDescription existing : clazzDesc.header) {
1786 if (existing.equals(headerDesc)) {
1787 headerDesc = existing;
1788 existed = true;
1789 }
1790 }
1791
1792 if (!existed) {
1793 //check if the only difference between the 7 and 8 version is the Profile annotation
1794 //if so, copy it to the pre-8 version, so save space
1795 for (ClassHeaderDescription existing : clazzDesc.header) {
1796 List<AnnotationDescription> annots = existing.classAnnotations;
1797
1798 if (annots != null) {
1799 for (AnnotationDescription ad : annots) {
1800 if (PROFILE_ANNOTATION.equals(ad.annotationType)) {
1801 existing.classAnnotations = new ArrayList<>(annots);
1802 existing.classAnnotations.remove(ad);
1803 if (existing.equals(headerDesc)) {
1804 headerDesc = existing;
1805 existed = true;
1806 }
1807 existing.classAnnotations = annots;
1808 break;
1809 }
1810 }
1811 }
1812 }
1813 }
1814
1815 headerDesc.versions += version;
2597 public static RequiresDescription deserialize(String data) {
2598 Map<String, String> attributes = splitAttributes(data);
2599
2600 Integer ver = attributes.containsKey("version")
2601 ? Integer.parseInt(attributes.get("version"))
2602 : null;
2603 int flags = Integer.parseInt(attributes.get("flags"), 16);
2604 return new RequiresDescription(attributes.get("name"),
2605 flags,
2606 ver);
2607 }
2608
2609 public static RequiresDescription create(ClassFile cf,
2610 RequiresEntry req) {
2611 String mod = getModuleName(cf, req.requires_index);
2612 Integer ver = getVersion(cf, req.requires_version_index);
2613 return new RequiresDescription(mod,
2614 req.requires_flags,
2615 ver);
2616 }
2617
2618 @Override
2619 public int hashCode() {
2620 int hash = 7;
2621 hash = 53 * hash + Objects.hashCode(this.moduleName);
2622 hash = 53 * hash + this.flags;
2623 hash = 53 * hash + Objects.hashCode(this.version);
2624 return hash;
2625 }
2626
2627 @Override
2628 public boolean equals(Object obj) {
2629 if (this == obj) {
2630 return true;
2631 }
2632 if (obj == null) {
2633 return false;
2634 }
2635 if (getClass() != obj.getClass()) {
2636 return false;
2637 }
2638 final RequiresDescription other = (RequiresDescription) obj;
2639 if (this.flags != other.flags) {
2640 return false;
2641 }
2642 if (!Objects.equals(this.moduleName, other.moduleName)) {
2643 return false;
2644 }
2645 if (!Objects.equals(this.version, other.version)) {
2646 return false;
2647 }
2648 return true;
2649 }
2650
2651 }
2652
2653 static class ProvidesDescription {
2654 final String interfaceName;
2655 final List<String> implNames;
2656
2657 public ProvidesDescription(String interfaceName,
2658 List<String> implNames) {
2659 this.interfaceName = interfaceName;
2660 this.implNames = implNames;
2661 }
2662
2663 public String serialize() {
2664 return "interface " + quote(interfaceName, true) +
2665 " impls " + quote(serializeList(implNames), true, true);
2666 }
2667
2668 public static ProvidesDescription deserialize(String data) {
2669 Map<String, String> attributes = splitAttributes(data);
2670 List<String> implsList =
2671 deserializeList(attributes.get("impls"),
2672 false);
2673 return new ProvidesDescription(attributes.get("interface"),
2674 implsList);
2675 }
2676
2677 public static ProvidesDescription create(ClassFile cf,
2678 ProvidesEntry prov) {
2679 String api = getClassName(cf, prov.provides_index);
2680 List<String> impls =
2681 Arrays.stream(prov.with_index)
2682 .mapToObj(wi -> getClassName(cf, wi))
2683 .collect(Collectors.toList());
2684 return new ProvidesDescription(api, impls);
2685 }
2686
2687 @Override
2688 public int hashCode() {
2689 int hash = 5;
2690 hash = 53 * hash + Objects.hashCode(this.interfaceName);
2691 hash = 53 * hash + Objects.hashCode(this.implNames);
2692 return hash;
2693 }
2694
2695 @Override
2696 public boolean equals(Object obj) {
2697 if (this == obj) {
2698 return true;
2699 }
2700 if (obj == null) {
2701 return false;
2702 }
2703 if (getClass() != obj.getClass()) {
2704 return false;
2705 }
2706 final ProvidesDescription other = (ProvidesDescription) obj;
2707 if (!Objects.equals(this.interfaceName, other.interfaceName)) {
2708 return false;
2709 }
2710 if (!Objects.equals(this.implNames, other.implNames)) {
2711 return false;
2712 }
2713 return true;
2714 }
2715 }
2716 }
2717
2718 public static class ClassDescription {
2719 String name;
2720 List<ClassHeaderDescription> header = new ArrayList<>();
2721 List<MethodDescription> methods = new ArrayList<>();
2722 List<FieldDescription> fields = new ArrayList<>();
2723
2724 public void write(Appendable output, String baselineVersion,
2725 String version) throws IOException {
2726 boolean inBaseline = false;
2727 boolean inVersion = false;
2728 for (ClassHeaderDescription chd : header) {
2729 if (baselineVersion != null &&
2730 chd.versions.contains(baselineVersion)) {
2731 inBaseline = true;
2732 }
2733 if (chd.versions.contains(version)) {
2734 inVersion = true;
2856 }
2857
2858 @Override
2859 public boolean equals(Object obj) {
2860 if (obj == null) {
2861 return false;
2862 }
2863 if (!super.equals(obj)) {
2864 return false;
2865 }
2866 final ClassHeaderDescription other = (ClassHeaderDescription) obj;
2867 if (!Objects.equals(this.extendsAttr, other.extendsAttr)) {
2868 return false;
2869 }
2870 if (!Objects.equals(this.implementsAttr, other.implementsAttr)) {
2871 return false;
2872 }
2873 if (!Objects.equals(this.nestHost, other.nestHost)) {
2874 return false;
2875 }
2876 if (!listEquals(this.nestMembers, other.nestMembers)) {
2877 return false;
2878 }
2879 return true;
2880 }
2881
2882 @Override
2883 public void write(Appendable output, String baselineVersion, String version) throws IOException {
2884 if (!versions.contains(version) ||
2885 (baselineVersion != null && versions.contains(baselineVersion) && versions.contains(version)))
2886 return ;
2887 output.append("header");
2888 if (extendsAttr != null)
2889 output.append(" extends " + extendsAttr);
2890 if (implementsAttr != null && !implementsAttr.isEmpty())
2891 output.append(" implements " + serializeList(implementsAttr));
2892 if (nestHost != null)
2893 output.append(" nestHost " + nestHost);
2894 if (nestMembers != null && !nestMembers.isEmpty())
2895 output.append(" nestMembers " + serializeList(nestMembers));
2896 writeAttributes(output);
|