@@ -34,15 +34,17 @@ class TemplateRecordEnhancer implements BiFunction<String, ClassVisitor, ClassVi
3434 private final String recordClassName ;
3535 private final String templateId ;
3636 private final String fragmentId ;
37+ private final String canonicalConstructorDescriptor ;
3738 private final List <MethodParameterInfo > parameters ;
3839 private final CheckedTemplateAdapter adapter ;
3940
4041 TemplateRecordEnhancer (ClassInfo interfaceToImplement , ClassInfo recordClass , String templateId , String fragmentId ,
41- List <MethodParameterInfo > parameters , CheckedTemplateAdapter adapter ) {
42+ String canonicalConstructorDescriptor , List <MethodParameterInfo > parameters , CheckedTemplateAdapter adapter ) {
4243 this .interfaceToImplement = interfaceToImplement ;
4344 this .recordClassName = recordClass .name ().toString ();
4445 this .templateId = templateId ;
4546 this .fragmentId = fragmentId ;
47+ this .canonicalConstructorDescriptor = canonicalConstructorDescriptor ;
4648 this .parameters = parameters ;
4749 this .adapter = adapter ;
4850 }
@@ -61,7 +63,7 @@ public TemplateRecordClassVisitor(ClassVisitor outputClassVisitor) {
6163 @ Override
6264 public MethodVisitor visitMethod (int access , String name , String descriptor , String signature , String [] exceptions ) {
6365 MethodVisitor ret = super .visitMethod (access , name , descriptor , signature , exceptions );
64- if (name .equals (MethodDescriptor .INIT )) {
66+ if (name .equals (MethodDescriptor .INIT ) && descriptor . equals ( canonicalConstructorDescriptor ) ) {
6567 return new TemplateRecordConstructorVisitor (ret );
6668 }
6769 return ret ;
@@ -126,74 +128,69 @@ public TemplateRecordConstructorVisitor(MethodVisitor outputVisitor) {
126128
127129 @ Override
128130 public void visitInsn (int opcode ) {
129- if (opcode != Opcodes .RETURN ) {
130- super .visitInsn (opcode );
131- }
132- }
131+ if (opcode == Opcodes .RETURN ) {
132+ visitVarInsn (Opcodes .ALOAD , 0 );
133+
134+ MethodDescriptor arcContainer = MethodDescriptor .ofMethod (Arc .class , "container" , ArcContainer .class );
135+ MethodDescriptor arcContainerInstance = MethodDescriptor .ofMethod (ArcContainer .class , "instance" ,
136+ InstanceHandle .class , Class .class , Annotation [].class );
137+ MethodDescriptor instanceHandleGet = MethodDescriptor .ofMethod (InstanceHandle .class , "get" , Object .class );
138+ MethodDescriptor templateProducerGetInjectableTemplate = MethodDescriptor .ofMethod (TemplateProducer .class ,
139+ "getInjectableTemplate" , Template .class , String .class );
140+ MethodDescriptor templateInstance = MethodDescriptor .ofMethod (Template .class , "instance" ,
141+ TemplateInstance .class );
142+ MethodDescriptor templateGetFragment = MethodDescriptor .ofMethod (Template .class , "getFragment" ,
143+ Template .Fragment .class , String .class );
144+ MethodDescriptor templateInstanceData = MethodDescriptor .ofMethod (TemplateInstance .class , "data" ,
145+ TemplateInstance .class , String .class , Object .class );
146+
147+ // Template template = Arc.container().instance(TemplateProducer.class).get().getInjectableTemplate("HelloResource/typedTemplate");
148+ visitMethodInsn (Opcodes .INVOKESTATIC , arcContainer .getDeclaringClass (), arcContainer .getName (),
149+ arcContainer .getDescriptor (),
150+ false );
151+ visitLdcInsn (org .objectweb .asm .Type .getType (TemplateProducer .class ));
152+ visitLdcInsn (0 );
153+ visitTypeInsn (Opcodes .ANEWARRAY , toInternalClassName (Annotation .class ));
154+ invokeInterface (this , arcContainerInstance );
155+ invokeInterface (this , instanceHandleGet );
156+ visitTypeInsn (Opcodes .CHECKCAST , toInternalClassName (TemplateProducer .class ));
157+ visitLdcInsn (templateId );
158+ visitMethodInsn (Opcodes .INVOKEVIRTUAL , templateProducerGetInjectableTemplate .getDeclaringClass (),
159+ templateProducerGetInjectableTemplate .getName (),
160+ templateProducerGetInjectableTemplate .getDescriptor (), false );
161+ if (fragmentId != null ) {
162+ // template = template.getFragment(id);
163+ visitLdcInsn (fragmentId );
164+ invokeInterface (this , templateGetFragment );
165+ }
166+ // templateInstance = template.instance();
167+ invokeInterface (this , templateInstance );
133168
134- @ Override
135- public void visitEnd () {
136- visitCode ();
137- visitVarInsn (Opcodes .ALOAD , 0 );
138-
139- MethodDescriptor arcContainer = MethodDescriptor .ofMethod (Arc .class , "container" , ArcContainer .class );
140- MethodDescriptor arcContainerInstance = MethodDescriptor .ofMethod (ArcContainer .class , "instance" ,
141- InstanceHandle .class , Class .class , Annotation [].class );
142- MethodDescriptor instanceHandleGet = MethodDescriptor .ofMethod (InstanceHandle .class , "get" , Object .class );
143- MethodDescriptor templateProducerGetInjectableTemplate = MethodDescriptor .ofMethod (TemplateProducer .class ,
144- "getInjectableTemplate" , Template .class , String .class );
145- MethodDescriptor templateInstance = MethodDescriptor .ofMethod (Template .class , "instance" , TemplateInstance .class );
146- MethodDescriptor templateGetFragment = MethodDescriptor .ofMethod (Template .class , "getFragment" ,
147- Template .Fragment .class , String .class );
148- MethodDescriptor templateInstanceData = MethodDescriptor .ofMethod (TemplateInstance .class , "data" ,
149- TemplateInstance .class , String .class , Object .class );
150-
151- // Template template = Arc.container().instance(TemplateProducer.class).get().getInjectableTemplate("HelloResource/typedTemplate");
152- visitMethodInsn (Opcodes .INVOKESTATIC , arcContainer .getDeclaringClass (), arcContainer .getName (),
153- arcContainer .getDescriptor (),
154- false );
155- visitLdcInsn (org .objectweb .asm .Type .getType (TemplateProducer .class ));
156- visitLdcInsn (0 );
157- visitTypeInsn (Opcodes .ANEWARRAY , toInternalClassName (Annotation .class ));
158- invokeInterface (this , arcContainerInstance );
159- invokeInterface (this , instanceHandleGet );
160- visitTypeInsn (Opcodes .CHECKCAST , toInternalClassName (TemplateProducer .class ));
161- visitLdcInsn (templateId );
162- visitMethodInsn (Opcodes .INVOKEVIRTUAL , templateProducerGetInjectableTemplate .getDeclaringClass (),
163- templateProducerGetInjectableTemplate .getName (),
164- templateProducerGetInjectableTemplate .getDescriptor (), false );
165- if (fragmentId != null ) {
166- // template = template.getFragment(id);
167- visitLdcInsn (fragmentId );
168- invokeInterface (this , templateGetFragment );
169- }
170- // templateInstance = template.instance();
171- invokeInterface (this , templateInstance );
169+ if (adapter != null ) {
170+ adapter .convertTemplateInstance (this );
171+ templateInstanceData = MethodDescriptor .ofMethod (adapter .templateInstanceBinaryName (), "data" ,
172+ adapter .templateInstanceBinaryName (), String .class , Object .class );
173+ }
172174
173- if (adapter != null ) {
174- adapter .convertTemplateInstance (this );
175- templateInstanceData = MethodDescriptor .ofMethod (adapter .templateInstanceBinaryName (), "data" ,
176- adapter .templateInstanceBinaryName (), String .class , Object .class );
177- }
175+ int slot = 1 ;
176+ for (int i = 0 ; i < parameters .size (); i ++) {
177+ // instance = instance.data("name", value);
178+ Type paramType = parameters .get (i ).type ();
179+ visitLdcInsn (parameters .get (i ).name ());
180+ visitVarInsn (AsmUtil .getLoadOpcode (paramType ), slot );
181+ AsmUtil .boxIfRequired (this , paramType );
182+ invokeInterface (this , templateInstanceData );
183+ slot += AsmUtil .getParameterSize (paramType );
184+ }
178185
179- int slot = 1 ;
180- for (int i = 0 ; i < parameters .size (); i ++) {
181- // instance = instance.data("name", value);
182- Type paramType = parameters .get (i ).type ();
183- visitLdcInsn (parameters .get (i ).name ());
184- visitVarInsn (AsmUtil .getLoadOpcode (paramType ), slot );
185- AsmUtil .boxIfRequired (this , paramType );
186- invokeInterface (this , templateInstanceData );
187- slot += AsmUtil .getParameterSize (paramType );
186+ FieldDescriptor quteTemplateInstanceDescriptor = FieldDescriptor .of (recordClassName , "qute$templateInstance" ,
187+ interfaceToImplement .name ().toString ());
188+ visitFieldInsn (Opcodes .PUTFIELD , quteTemplateInstanceDescriptor .getDeclaringClass (),
189+ quteTemplateInstanceDescriptor .getName (), quteTemplateInstanceDescriptor .getType ());
190+ super .visitInsn (Opcodes .RETURN );
191+ } else {
192+ super .visitInsn (opcode );
188193 }
189-
190- FieldDescriptor quteTemplateInstanceDescriptor = FieldDescriptor .of (recordClassName , "qute$templateInstance" ,
191- interfaceToImplement .name ().toString ());
192- visitFieldInsn (Opcodes .PUTFIELD , quteTemplateInstanceDescriptor .getDeclaringClass (),
193- quteTemplateInstanceDescriptor .getName (), quteTemplateInstanceDescriptor .getType ());
194- super .visitInsn (Opcodes .RETURN );
195- super .visitEnd ();
196- visitMaxs (-1 , -1 );
197194 }
198195
199196 }
0 commit comments