< prev index next >

src/java.base/share/classes/jdk/internal/module/ModuleInfoWriter.java

Print this page
rev 47453 : imported patch jdk-new-asm-update.patch

*** 26,75 **** import java.io.IOException; import java.io.OutputStream; import java.lang.module.ModuleDescriptor; import java.nio.ByteBuffer; import java.util.stream.Stream; import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.Opcodes; - import static jdk.internal.module.ClassFileAttributes.*; - import static jdk.internal.module.ClassFileConstants.ACC_MODULE; - /** * Utility class to write a ModuleDescriptor as a module-info.class. */ public final class ModuleInfoWriter { private ModuleInfoWriter() { } /** * Writes the given module descriptor to a module-info.class file, * returning it in a byte array. */ private static byte[] toModuleInfo(ModuleDescriptor md, ModuleTarget target) { ClassWriter cw = new ClassWriter(0); ! cw.visit(Opcodes.V1_9, ACC_MODULE, "module-info", null, null, null); ! cw.visitAttribute(new ModuleAttribute(md)); ! // for tests: write the ModulePackages attribute when there are packages ! // that aren't exported or open Stream<String> exported = md.exports().stream() .map(ModuleDescriptor.Exports::source); Stream<String> open = md.opens().stream() .map(ModuleDescriptor.Opens::source); long exportedOrOpen = Stream.concat(exported, open).distinct().count(); ! if (md.packages().size() > exportedOrOpen) ! cw.visitAttribute(new ModulePackagesAttribute(md.packages())); ! // write ModuleMainClass if the module has a main class ! md.mainClass().ifPresent(mc -> cw.visitAttribute(new ModuleMainClassAttribute(mc))); ! // write ModuleTarget if there is a target platform ! if (target != null) { cw.visitAttribute(new ModuleTargetAttribute(target.targetPlatform())); } cw.visitEnd(); return cw.toByteArray(); --- 26,156 ---- import java.io.IOException; import java.io.OutputStream; import java.lang.module.ModuleDescriptor; import java.nio.ByteBuffer; + import java.util.Map; import java.util.stream.Stream; import jdk.internal.org.objectweb.asm.ClassWriter; + import jdk.internal.org.objectweb.asm.ModuleVisitor; import jdk.internal.org.objectweb.asm.Opcodes; + import jdk.internal.org.objectweb.asm.commons.ModuleTargetAttribute; + import static jdk.internal.org.objectweb.asm.Opcodes.*; /** * Utility class to write a ModuleDescriptor as a module-info.class. */ public final class ModuleInfoWriter { + private static final Map<ModuleDescriptor.Modifier, Integer> + MODULE_MODS_TO_FLAGS = Map.of( + ModuleDescriptor.Modifier.OPEN, ACC_OPEN, + ModuleDescriptor.Modifier.SYNTHETIC, ACC_SYNTHETIC, + ModuleDescriptor.Modifier.MANDATED, ACC_MANDATED + ); + + private static final Map<ModuleDescriptor.Requires.Modifier, Integer> + REQUIRES_MODS_TO_FLAGS = Map.of( + ModuleDescriptor.Requires.Modifier.TRANSITIVE, ACC_TRANSITIVE, + ModuleDescriptor.Requires.Modifier.STATIC, ACC_STATIC_PHASE, + ModuleDescriptor.Requires.Modifier.SYNTHETIC, ACC_SYNTHETIC, + ModuleDescriptor.Requires.Modifier.MANDATED, ACC_MANDATED + ); + + private static final Map<ModuleDescriptor.Exports.Modifier, Integer> + EXPORTS_MODS_TO_FLAGS = Map.of( + ModuleDescriptor.Exports.Modifier.SYNTHETIC, ACC_SYNTHETIC, + ModuleDescriptor.Exports.Modifier.MANDATED, ACC_MANDATED + ); + + private static final Map<ModuleDescriptor.Opens.Modifier, Integer> + OPENS_MODS_TO_FLAGS = Map.of( + ModuleDescriptor.Opens.Modifier.SYNTHETIC, ACC_SYNTHETIC, + ModuleDescriptor.Opens.Modifier.MANDATED, ACC_MANDATED + ); + + private static final String[] EMPTY_STRING_ARRAY = new String[0]; + private ModuleInfoWriter() { } /** * Writes the given module descriptor to a module-info.class file, * returning it in a byte array. */ private static byte[] toModuleInfo(ModuleDescriptor md, ModuleTarget target) { ClassWriter cw = new ClassWriter(0); ! cw.visit(Opcodes.V9, ACC_MODULE, "module-info", null, null, null); ! int moduleFlags = md.modifiers().stream() ! .map(MODULE_MODS_TO_FLAGS::get) ! .reduce(0, (x, y) -> (x | y)); ! String vs = md.rawVersion().orElse(null); ! ModuleVisitor mv = cw.visitModule(md.name(), moduleFlags, vs); ! ! // requires ! for (ModuleDescriptor.Requires r : md.requires()) { ! int flags = r.modifiers().stream() ! .map(REQUIRES_MODS_TO_FLAGS::get) ! .reduce(0, (x, y) -> (x | y)); ! vs = r.rawCompiledVersion().orElse(null); ! mv.visitRequire(r.name(), flags, vs); ! } ! ! // exports ! for (ModuleDescriptor.Exports e : md.exports()) { ! int flags = e.modifiers().stream() ! .map(EXPORTS_MODS_TO_FLAGS::get) ! .reduce(0, (x, y) -> (x | y)); ! String[] targets = e.targets().toArray(EMPTY_STRING_ARRAY); ! mv.visitExport(e.source().replace('.', '/'), flags, targets); ! } ! ! // opens ! for (ModuleDescriptor.Opens opens : md.opens()) { ! int flags = opens.modifiers().stream() ! .map(OPENS_MODS_TO_FLAGS::get) ! .reduce(0, (x, y) -> (x | y)); ! String[] targets = opens.targets().toArray(EMPTY_STRING_ARRAY); ! mv.visitOpen(opens.source().replace('.', '/'), flags, targets); ! } ! ! // uses ! md.uses().stream().map(sn -> sn.replace('.', '/')).forEach(mv::visitUse); ! ! // provides ! for (ModuleDescriptor.Provides p : md.provides()) { ! mv.visitProvide(p.service().replace('.', '/'), ! p.providers() ! .stream() ! .map(pn -> pn.replace('.', '/')) ! .toArray(String[]::new)); ! } ! ! // add the ModulePackages attribute when there are packages that aren't ! // exported or open Stream<String> exported = md.exports().stream() .map(ModuleDescriptor.Exports::source); Stream<String> open = md.opens().stream() .map(ModuleDescriptor.Opens::source); long exportedOrOpen = Stream.concat(exported, open).distinct().count(); ! if (md.packages().size() > exportedOrOpen) { ! md.packages().stream() ! .map(pn -> pn.replace('.', '/')) ! .forEach(mv::visitPackage); ! } ! // ModuleMainClass attribute ! md.mainClass() ! .map(mc -> mc.replace('.', '/')) ! .ifPresent(mv::visitMainClass); ! mv.visitEnd(); ! ! // write ModuleTarget attribute if there is a target platform ! if (target != null && target.targetPlatform().length() > 0) { cw.visitAttribute(new ModuleTargetAttribute(target.targetPlatform())); } cw.visitEnd(); return cw.toByteArray();
< prev index next >