@NotNull private ClassBuilder createClassBuilder() { ClassBuilder classBuilder = state .getFactory() .newVisitor( NO_ORIGIN, newLambdaType, inliningContext.getRoot().callElement.getContainingFile()); return new RemappingClassBuilder( classBuilder, new AsmTypeRemapper( inliningContext.typeRemapper, inliningContext.getRoot().typeParameterMappings == null, transformationResult)); }
@NotNull private InlineResult inlineMethod( @NotNull AnonymousObjectGeneration anonymousObjectGen, @NotNull FieldRemapper parentRemapper, @NotNull MethodVisitor deferringVisitor, @NotNull MethodNode sourceNode, @NotNull ParametersBuilder capturedBuilder, boolean isConstructor) { ReifiedTypeParametersUsages typeParametersToReify = inliningContext.reifedTypeInliner.reifyInstructions(sourceNode); Parameters parameters = isConstructor ? capturedBuilder.buildParameters() : getMethodParametersWithCaptured(capturedBuilder, sourceNode); RegeneratedLambdaFieldRemapper remapper = new RegeneratedLambdaFieldRemapper( oldObjectType.getInternalName(), newLambdaType.getInternalName(), parameters, anonymousObjectGen.getCapturedLambdasToInline(), parentRemapper, isConstructor); MethodInliner inliner = new MethodInliner( sourceNode, parameters, inliningContext.subInline(inliningContext.nameGenerator.subGenerator("lambda")), remapper, isSameModule, "Transformer for " + anonymousObjectGen.getOwnerInternalName(), sourceMapper, new InlineCallSiteInfo( anonymousObjectGen.getOwnerInternalName(), sourceNode.name, isConstructor ? anonymousObjectGen.getNewConstructorDescriptor() : sourceNode.desc)); InlineResult result = inliner.doInline( deferringVisitor, new LocalVarRemapper(parameters, 0), false, LabelOwner.NOT_APPLICABLE); result.getReifiedTypeParametersUsages().mergeAll(typeParametersToReify); deferringVisitor.visitMaxs(-1, -1); return result; }
public InlineResult doInline( @NotNull MethodVisitor adapter, @NotNull LocalVarRemapper remapper, boolean remapReturn, @NotNull LabelOwner labelOwner) { // analyze body MethodNode transformedNode = markPlacesForInlineAndRemoveInlinable(node); // substitute returns with "goto end" instruction to keep non local returns in lambdas Label end = new Label(); transformedNode = doInline(transformedNode); removeClosureAssertions(transformedNode); InsnList instructions = transformedNode.instructions; instructions.resetLabels(); MethodNode resultNode = new MethodNode( InlineCodegenUtil.API, transformedNode.access, transformedNode.name, transformedNode.desc, transformedNode.signature, ArrayUtil.toStringArray(transformedNode.exceptions)); RemapVisitor visitor = new RemapVisitor(resultNode, remapper, nodeRemapper); try { transformedNode.accept(visitor); } catch (Exception e) { throw wrapException(e, transformedNode, "couldn't inline method call"); } resultNode.visitLabel(end); if (inliningContext.isRoot()) { InternalFinallyBlockInliner.processInlineFunFinallyBlocks(resultNode, lambdasFinallyBlocks); } processReturns(resultNode, labelOwner, remapReturn, end); // flush transformed node to output resultNode.accept(new InliningInstructionAdapter(adapter)); return result; }
private void writeOuterInfo(@NotNull ClassVisitor visitor) { InlineCallSiteInfo info = inliningContext.getCallSiteInfo(); visitor.visitOuterClass( info.getOwnerClassName(), info.getFunctionName(), info.getFunctionDesc()); }