void (ClassNode node, TextBuffer buffer, Exprent method_object, int indent, BytecodeMappingTracer origTracer) { ClassWrapper wrapper = node.getWrapper(); if (wrapper == null) { return; } boolean lambdaToAnonymous = DecompilerContext.getOption(IFernflowerPreferences.LAMBDA_TO_ANONYMOUS_CLASS); ClassNode outerNode = (ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE); DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASS_NODE, node); BytecodeMappingTracer tracer = new BytecodeMappingTracer(origTracer.getCurrentSourceLine()); try { StructClass cl = wrapper.getClassStruct(); DecompilerContext.getLogger().startWriteClass(node.simpleName); if (node.lambdaInformation.is_method_reference) { if (!node.lambdaInformation.is_content_method_static && method_object != null) { // reference to a virtual method buffer.append(method_object.toJava(indent, tracer)); } else { // reference to a static method buffer.append(ExprProcessor.getCastTypeName(new VarType(node.lambdaInformation.content_class_name, true), Collections.emptyList())); } buffer.append("::") .append(CodeConstants.INIT_NAME.equals(node.lambdaInformation.content_method_name) ? "new" : node.lambdaInformation.content_method_name); } else { // lambda method StructMethod mt = cl.getMethod(node.lambdaInformation.content_method_key); MethodWrapper methodWrapper = wrapper.getMethodWrapper(mt.getName(), mt.getDescriptor()); MethodDescriptor md_content = MethodDescriptor.parseDescriptor(node.lambdaInformation.content_method_descriptor); MethodDescriptor md_lambda = MethodDescriptor.parseDescriptor(node.lambdaInformation.method_descriptor); List<TypeAnnotation> parameterTypeAnnotations = TargetInfo.FormalParameterTarget.extract(TypeAnnotation.listFrom(mt)); boolean explicitlyTyped = !parameterTypeAnnotations.isEmpty(); if (!lambdaToAnonymous) { buffer.append('('); boolean firstParameter = true; int index = node.lambdaInformation.is_content_method_static ? 0 : 1; int start_index = md_content.params.length - md_lambda.params.length; for (int i = 0; i < md_content.params.length; i++) { if (i >= start_index) { if (!firstParameter) { buffer.append(", "); } if (explicitlyTyped) { List<TypeAnnotation> iParameterTypeAnnotations = TargetInfo.FormalParameterTarget.extract(parameterTypeAnnotations, i); VarType type = md_content.params[i]; buffer.append(ExprProcessor.getCastTypeName(type, TypeAnnotationWriteHelper.create(iParameterTypeAnnotations))); buffer.append(' '); } String parameterName = methodWrapper.varproc.getVarName(new VarVersionPair(index, 0)); buffer.append(parameterName == null ? "param" + index : parameterName); // null iff decompiled with errors firstParameter = false; } index += md_content.params[i].getStackSize(); } buffer.append(") ->"); } buffer.append(" {").appendLineSeparator(); tracer.incrementCurrentSourceLine(); methodLambdaToJava(node, wrapper, mt, buffer, indent + 1, !lambdaToAnonymous, tracer); buffer.appendIndent(indent).append("}"); addTracer(cl, mt, tracer); } } finally { DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASS_NODE, outerNode); } DecompilerContext.getLogger().endWriteClass(); }