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 com.sun.tools.classfile;
  27 
  28 import java.io.IOException;
  29 
  30 import com.sun.tools.classfile.ConstantPool.CONSTANT_Module_info;
  31 
  32 /**
  33  * See Jigsaw.
  34  *
  35  *  <p><b>This is NOT part of any supported API.
  36  *  If you write code that depends on this, you do so at your own risk.
  37  *  This code and its internal interfaces are subject to change or
  38  *  deletion without notice.</b>
  39  */
  40 public class Module_attribute extends Attribute {
  41     public static final int ACC_TRANSITIVE      =   0x20;
  42     public static final int ACC_STATIC_PHASE    =   0x40;
  43     public static final int ACC_OPEN            =   0x20;
  44     public static final int ACC_SYNTHETIC       = 0x1000;
  45     public static final int ACC_MANDATED        = 0x8000;
  46 
  47     Module_attribute(ClassReader cr, int name_index, int length) throws IOException {
  48         super(name_index, length);
  49 
  50         module_name = cr.readUnsignedShort();
  51         module_flags = cr.readUnsignedShort();
  52 
  53         module_version_index = cr.readUnsignedShort();
  54 
  55         requires_count = cr.readUnsignedShort();
  56         requires = new RequiresEntry[requires_count];
  57         for (int i = 0; i < requires_count; i++)
  58             requires[i] = new RequiresEntry(cr);
  59 
  60         exports_count = cr.readUnsignedShort();
  61         exports = new ExportsEntry[exports_count];
  62         for (int i = 0; i < exports_count; i++)
  63             exports[i] = new ExportsEntry(cr);
  64 
  65         opens_count = cr.readUnsignedShort();
  66         opens = new OpensEntry[opens_count];
  67         for (int i = 0; i < opens_count; i++)
  68             opens[i] = new OpensEntry(cr);
  69 
  70         uses_count = cr.readUnsignedShort();
  71         uses_index = new int[uses_count];
  72         for (int i = 0; i < uses_count; i++)
  73             uses_index[i] = cr.readUnsignedShort();
  74 
  75         provides_count = cr.readUnsignedShort();
  76         provides = new ProvidesEntry[provides_count];
  77         for (int i = 0; i < provides_count; i++)
  78             provides[i] = new ProvidesEntry(cr);
  79     }
  80 
  81     public Module_attribute(int name_index,
  82             int module_name,
  83             int module_flags,
  84             int module_version_index,
  85             RequiresEntry[] requires,
  86             ExportsEntry[] exports,
  87             OpensEntry[] opens,
  88             int[] uses,
  89             ProvidesEntry[] provides) {
  90         super(name_index, 2);
  91         this.module_name = module_name;
  92         this.module_flags = module_flags;
  93         this.module_version_index = module_version_index;
  94         requires_count = requires.length;
  95         this.requires = requires;
  96         exports_count = exports.length;
  97         this.exports = exports;
  98         opens_count = opens.length;
  99         this.opens = opens;
 100         uses_count = uses.length;
 101         this.uses_index = uses;
 102         provides_count = provides.length;
 103         this.provides = provides;
 104     }
 105 
 106     public String getUses(int index, ConstantPool constant_pool) throws ConstantPoolException {
 107         int i = uses_index[index];
 108         return constant_pool.getClassInfo(i).getName();
 109     }
 110 
 111     @Override
 112     public <R, D> R accept(Visitor<R, D> visitor, D data) {
 113         return visitor.visitModule(this, data);
 114     }
 115 
 116     public final int module_name;
 117     public final int module_flags;
 118     public final int module_version_index;
 119     public final int requires_count;
 120     public final RequiresEntry[] requires;
 121     public final int exports_count;
 122     public final ExportsEntry[] exports;
 123     public final int opens_count;
 124     public final OpensEntry[] opens;
 125     public final int uses_count;
 126     public final int[] uses_index;
 127     public final int provides_count;
 128     public final ProvidesEntry[] provides;
 129 
 130     public static class RequiresEntry {
 131         RequiresEntry(ClassReader cr) throws IOException {
 132             requires_index = cr.readUnsignedShort();
 133             requires_flags = cr.readUnsignedShort();
 134             requires_version_index = cr.readUnsignedShort();
 135         }
 136 
 137         public RequiresEntry(int index, int flags, int version_index) {
 138             this.requires_index = index;
 139             this.requires_flags = flags;
 140             this.requires_version_index = version_index;
 141         }
 142 
 143         public String getRequires(ConstantPool constant_pool) throws ConstantPoolException {
 144             CONSTANT_Module_info info = constant_pool.getModuleInfo(requires_index);
 145             return info.getName();
 146         }
 147 
 148         public static final int length = 4;
 149 
 150         public final int requires_index;
 151         public final int requires_flags;
 152         public final int requires_version_index;
 153     }
 154 
 155     public static class ExportsEntry {
 156         ExportsEntry(ClassReader cr) throws IOException {
 157             exports_index = cr.readUnsignedShort();
 158             exports_flags = cr.readUnsignedShort();
 159             exports_to_count = cr.readUnsignedShort();
 160             exports_to_index = new int[exports_to_count];
 161             for (int i = 0; i < exports_to_count; i++)
 162                 exports_to_index[i] = cr.readUnsignedShort();
 163         }
 164 
 165         public ExportsEntry(int index, int flags, int[] to) {
 166             this.exports_index = index;
 167             this.exports_flags = flags;
 168             this.exports_to_count = to.length;
 169             this.exports_to_index = to;
 170         }
 171 
 172         public int length() {
 173             return 4 + 2 * exports_to_index.length;
 174         }
 175 
 176         public final int exports_index;
 177         public final int exports_flags;
 178         public final int exports_to_count;
 179         public final int[] exports_to_index;
 180     }
 181 
 182     public static class OpensEntry {
 183         OpensEntry(ClassReader cr) throws IOException {
 184             opens_index = cr.readUnsignedShort();
 185             opens_flags = cr.readUnsignedShort();
 186             opens_to_count = cr.readUnsignedShort();
 187             opens_to_index = new int[opens_to_count];
 188             for (int i = 0; i < opens_to_count; i++)
 189                 opens_to_index[i] = cr.readUnsignedShort();
 190         }
 191 
 192         public OpensEntry(int index, int flags, int[] to) {
 193             this.opens_index = index;
 194             this.opens_flags = flags;
 195             this.opens_to_count = to.length;
 196             this.opens_to_index = to;
 197         }
 198 
 199         public int length() {
 200             return 4 + 2 * opens_to_index.length;
 201         }
 202 
 203         public final int opens_index;
 204         public final int opens_flags;
 205         public final int opens_to_count;
 206         public final int[] opens_to_index;
 207     }
 208 
 209     public static class ProvidesEntry {
 210         ProvidesEntry(ClassReader cr) throws IOException {
 211             provides_index = cr.readUnsignedShort();
 212             with_count = cr.readUnsignedShort();
 213             with_index = new int[with_count];
 214             for (int i = 0; i < with_count; i++)
 215                 with_index[i] = cr.readUnsignedShort();
 216         }
 217 
 218         public ProvidesEntry(int provides, int[] with) {
 219             this.provides_index = provides;
 220             this.with_count = with.length;
 221             this.with_index = with;
 222         }
 223 
 224         public static final int length = 4;
 225 
 226         public final int provides_index;
 227         public final int with_count;
 228         public final int[] with_index;
 229     }
 230 }