3030import net .bytebuddy .description .method .ParameterList ;
3131import net .bytebuddy .description .modifier .ModifierContributor ;
3232import net .bytebuddy .description .modifier .Visibility ;
33+ import net .bytebuddy .description .module .ModuleDescription ;
3334import net .bytebuddy .description .type .PackageDescription ;
3435import net .bytebuddy .description .type .RecordComponentDescription ;
3536import net .bytebuddy .description .type .RecordComponentList ;
7980import org .objectweb .asm .Handle ;
8081import org .objectweb .asm .Label ;
8182import org .objectweb .asm .MethodVisitor ;
83+ import org .objectweb .asm .ModuleVisitor ;
8284import org .objectweb .asm .Opcodes ;
8385import org .objectweb .asm .RecordComponentVisitor ;
8486import org .objectweb .asm .Type ;
100102import java .util .LinkedHashMap ;
101103import java .util .LinkedHashSet ;
102104import java .util .List ;
105+ import java .util .Map ;
103106import java .util .Set ;
104107
105108import static net .bytebuddy .matcher .ElementMatchers .is ;
@@ -6076,7 +6079,7 @@ public ContextClassVisitor wrap(ClassVisitor classVisitor, int writerFlags, int
60766079 fields ,
60776080 methods ,
60786081 asmVisitorWrapper .mergeWriter (writerFlags ),
6079- asmVisitorWrapper .mergeReader (readerFlags )), implementationContext ), implementationContext );
6082+ asmVisitorWrapper .mergeReader (readerFlags )), implementationContext , instrumentedType . toModuleDescription () ), implementationContext );
60806083 }
60816084
60826085 @ Override
@@ -6108,6 +6111,10 @@ protected UnresolvedType create(TypeInitializer typeInitializer, ClassDumpAction
61086111 ? TypeDescription .ForLoadedType .of (Object .class )
61096112 : instrumentedType .getSuperClass ().asErasure ()).getInternalName (),
61106113 instrumentedType .getInterfaces ().asErasures ().toInternalNames ());
6114+ ModuleDescription moduleDescription = instrumentedType .toModuleDescription ();
6115+ if (moduleDescription != null ) {
6116+ moduleDescription .accept (classVisitor );
6117+ }
61116118 if (!instrumentedType .isNestHost ()) {
61126119 classVisitor .visitNestHost (instrumentedType .getNestHost ().getInternalName ());
61136120 }
@@ -6181,6 +6188,12 @@ protected class CreationClassVisitor extends MetadataAwareClassVisitor {
61816188 */
61826189 private final Implementation .Context .ExtractableView implementationContext ;
61836190
6191+ /**
6192+ * The underlying module information or {@code null} if no such information is provided.
6193+ */
6194+ @ MaybeNull
6195+ private final ModuleDescription moduleDescription ;
6196+
61846197 /**
61856198 * The declared types that have been visited.
61866199 */
@@ -6201,10 +6214,29 @@ protected class CreationClassVisitor extends MetadataAwareClassVisitor {
62016214 *
62026215 * @param classVisitor The class visitor being wrapped.
62036216 * @param implementationContext The implementation context to apply.
6217+ * @param moduleDescription The underlying module information or {@code null} if no such information is provided.
62046218 */
6205- protected CreationClassVisitor (ClassVisitor classVisitor , Implementation .Context .ExtractableView implementationContext ) {
6219+ protected CreationClassVisitor (ClassVisitor classVisitor ,
6220+ Implementation .Context .ExtractableView implementationContext ,
6221+ @ MaybeNull ModuleDescription moduleDescription ) {
62066222 super (OpenedClassReader .ASM_API , classVisitor );
62076223 this .implementationContext = implementationContext ;
6224+ this .moduleDescription = moduleDescription ;
6225+ }
6226+
6227+ @ Override
6228+ protected void onModule () {
6229+ if (moduleDescription != null ) {
6230+ moduleDescription .accept (cv );
6231+ }
6232+ }
6233+
6234+ @ Override
6235+ @ MaybeNull
6236+ protected ModuleVisitor onVisitModule (String name , int modifiers , @ MaybeNull String version ) {
6237+ return moduleDescription == null ? null : new PatchingModuleVisitor (cv .visitModule (moduleDescription .getActualName (),
6238+ moduleDescription .getModifiers (),
6239+ moduleDescription .getVersion ()), moduleDescription );
62086240 }
62096241
62106242 @ Override
@@ -6263,6 +6295,181 @@ protected void onVisitEnd() {
62636295 }
62646296 }
62656297
6298+ /**
6299+ * A class visitor that applies the subclass creation as a wrapper.
6300+ */
6301+ protected static class PatchingModuleVisitor extends ModuleVisitor {
6302+
6303+ /**
6304+ * The internal name of the main class or {@code null} if no main class is defined.
6305+ */
6306+ @ MaybeNull
6307+ private String mainClass ;
6308+
6309+ /**
6310+ * The internal name of all packages of the module.
6311+ */
6312+ private final Set <String > packages ;
6313+
6314+ /**
6315+ * A mapping of required modules to their configuration.
6316+ */
6317+ private final Map <String , ModuleDescription .Requires > requires ;
6318+
6319+ /**
6320+ * A mapping of the internal names of exported packages to their configuration.
6321+ */
6322+ private final Map <String , ModuleDescription .Exports > exports ;
6323+
6324+ /**
6325+ * A mapping of the internal names of opened packages to their configuration.
6326+ */
6327+ private final Map <String , ModuleDescription .Opens > opens ;
6328+
6329+ /**
6330+ * A collection of internal names of used services.
6331+ */
6332+ private final Set <String > uses ;
6333+
6334+ /**
6335+ * A mapping of the internal names of provided services to the internal names of the provided implementations.
6336+ */
6337+ private final Map <String , Set <String >> provides ;
6338+
6339+ /**
6340+ * Creates a module visitor that patches the module implementation.
6341+ *
6342+ * @param moduleVisitor The module visitor to which the data is delegated to.
6343+ * @param moduleDescription A description of the module.
6344+ */
6345+ protected PatchingModuleVisitor (ModuleVisitor moduleVisitor , ModuleDescription moduleDescription ) {
6346+ super (OpenedClassReader .ASM_API , moduleVisitor );
6347+ mainClass = moduleDescription .getMainClass ();
6348+ if (mainClass != null ) {
6349+ mainClass = mainClass .replace ('.' , '/' );
6350+ }
6351+ packages = new LinkedHashSet <String >();
6352+ for (String aPackage : moduleDescription .getPackages ()) {
6353+ packages .add (aPackage .replace ('.' , '/' ));
6354+ }
6355+ requires = new LinkedHashMap <String , ModuleDescription .Requires >(moduleDescription .getRequires ());
6356+ exports = new LinkedHashMap <String , ModuleDescription .Exports >();
6357+ for (Map .Entry <String , ModuleDescription .Exports > entry : moduleDescription .getExports ().entrySet ()) {
6358+ exports .put (entry .getKey ().replace ('.' , '/' ), entry .getValue ());
6359+ }
6360+ opens = new LinkedHashMap <String , ModuleDescription .Opens >();
6361+ for (Map .Entry <String , ModuleDescription .Opens > entry : moduleDescription .getOpens ().entrySet ()) {
6362+ opens .put (entry .getKey ().replace ('.' , '/' ), entry .getValue ());
6363+ }
6364+ uses = new LinkedHashSet <String >();
6365+ for (String use : moduleDescription .getUses ()) {
6366+ uses .add (use .replace ('.' , '/' ));
6367+ }
6368+ provides = new LinkedHashMap <String , Set <String >>();
6369+ for (Map .Entry <String , ModuleDescription .Provides > entry : moduleDescription .getProvides ().entrySet ()) {
6370+ Set <String > providers = new LinkedHashSet <String >();
6371+ for (String provider : entry .getValue ().getProviders ()) {
6372+ providers .add (provider .replace ('.' , '/' ));
6373+ }
6374+ provides .put (entry .getKey ().replace ('.' , '/' ), providers );
6375+ }
6376+ }
6377+
6378+ @ Override
6379+ public void visitMainClass (String mainClass ) {
6380+ if (this .mainClass != null ) {
6381+ super .visitMainClass (this .mainClass );
6382+ this .mainClass = null ;
6383+ }
6384+ }
6385+
6386+ @ Override
6387+ public void visitPackage (String aPackage ) {
6388+ super .visitPackage (aPackage );
6389+ packages .remove (aPackage );
6390+ }
6391+
6392+ @ Override
6393+ public void visitRequire (String module , int modifiers , @ MaybeNull String version ) {
6394+ ModuleDescription .Requires requires = this .requires .remove (module );
6395+ if (requires != null ) {
6396+ super .visitRequire (module , requires .getModifiers (), requires .getVersion ());
6397+ } else {
6398+ super .visitRequire (module , modifiers , version );
6399+ }
6400+ }
6401+
6402+ @ Override
6403+ public void visitExport (String aPackage , int modifiers , @ MaybeNull String ... module ) {
6404+ ModuleDescription .Exports exports = this .exports .remove (aPackage );
6405+ if (exports != null ) {
6406+ super .visitExport (aPackage , exports .getModifiers (), exports .getTargets ().isEmpty ()
6407+ ? null
6408+ : exports .getTargets ().toArray (new String [0 ]));
6409+ } else {
6410+ super .visitExport (aPackage , modifiers , module );
6411+ }
6412+ }
6413+
6414+ @ Override
6415+ public void visitOpen (String aPackage , int modifiers , @ MaybeNull String ... module ) {
6416+ ModuleDescription .Opens opens = this .opens .remove (aPackage );
6417+ if (opens != null ) {
6418+ super .visitOpen (aPackage , opens .getModifiers (), opens .getTargets ().isEmpty ()
6419+ ? null
6420+ : opens .getTargets ().toArray (new String [0 ]));
6421+ } else {
6422+ super .visitOpen (aPackage , modifiers , module );
6423+ }
6424+ }
6425+
6426+ @ Override
6427+ public void visitUse (String service ) {
6428+ uses .remove (service );
6429+ super .visitUse (service );
6430+ }
6431+
6432+ @ Override
6433+ public void visitProvide (String service , String ... provider ) {
6434+ Set <String > providers = this .provides .remove (service );
6435+ if (providers != null ) {
6436+ super .visitProvide (service , providers .toArray (new String [0 ]));
6437+ } else {
6438+ super .visitProvide (service , provider );
6439+ }
6440+ }
6441+
6442+ @ Override
6443+ public void visitEnd () {
6444+ if (mainClass != null ) {
6445+ super .visitMainClass (mainClass );
6446+ }
6447+ for (String aPackage : packages ) {
6448+ super .visitPackage (aPackage );
6449+ }
6450+ for (Map .Entry <String , ModuleDescription .Requires > entry : requires .entrySet ()) {
6451+ super .visitRequire (entry .getKey (), entry .getValue ().getModifiers (), entry .getValue ().getVersion ());
6452+ }
6453+ for (Map .Entry <String , ModuleDescription .Exports > entry : exports .entrySet ()) {
6454+ super .visitExport (entry .getKey (),
6455+ entry .getValue ().getModifiers (),
6456+ entry .getValue ().getTargets ().isEmpty () ? null : entry .getValue ().getTargets ().toArray (new String [0 ]));
6457+ }
6458+ for (Map .Entry <String , ModuleDescription .Opens > entry : opens .entrySet ()) {
6459+ super .visitOpen (entry .getKey (),
6460+ entry .getValue ().getModifiers (),
6461+ entry .getValue ().getTargets ().isEmpty () ? null : entry .getValue ().getTargets ().toArray (new String [0 ]));
6462+ }
6463+ for (String use : uses ) {
6464+ super .visitUse (use );
6465+ }
6466+ for (Map .Entry <String , Set <String >> entry : provides .entrySet ()) {
6467+ super .visitProvide (entry .getKey (), entry .getValue ().isEmpty () ? null : entry .getValue ().toArray (new String [0 ]));
6468+ }
6469+ super .visitEnd ();
6470+ }
6471+ }
6472+
62666473 /**
62676474 * A context class visitor based on an {@link Implementation.Context}.
62686475 */
0 commit comments