private void appendExpressionMethod(@Nonnull StringBuilder code, @Nonnull String expression) throws ExpressionCompileException {
		// Need to build the method structure to house the expression.
		// We'll start off with the access level.
		int parameterVarIndex = 0;
		if (AccessFlag.isPublic(methodFlags))
			code.append("public ");
		else if (AccessFlag.isProtected(methodFlags))
			code.append("protected ");
		else if (AccessFlag.isPrivate(methodFlags))
			code.append("private ");
		if (AccessFlag.isStatic(methodFlags))
			code.append("static ");
		else
			parameterVarIndex++;

		// Add the return type.
		ClassType returnType = methodType.returnType();
		if (returnType instanceof PrimitiveType primitiveReturn) {
			code.append(primitiveReturn.name()).append(' ');
		} else if (returnType instanceof InstanceType instanceType) {
			code.append(instanceType.internalName().replace('/', '.')).append(' ');
		} else if (returnType instanceof ArrayType arrayReturn) {
			ClassType componentReturnType = arrayReturn.componentType();
			if (componentReturnType instanceof PrimitiveType primitiveReturn) {
				code.append(primitiveReturn.name());
			} else if (componentReturnType instanceof InstanceType instanceType) {
				code.append(instanceType.internalName().replace('/', '.'));
			}
			code.append("[]".repeat(arrayReturn.dimensions()));
		}

		// Now the method name.
		code.append(' ').append(methodName).append('(');

		// And now the parameters.
		int parameterCount = methodType.parameterTypes().size();
		Set<String> usedVariables = new HashSet<>();
		for (int i = 0; i < parameterCount; i++) {
			// Lookup the parameter variable
			LocalVariable parameterVariable = getParameterVariable(parameterVarIndex, i);
			String parameterName = parameterVariable.getName();

			// Record the parameter as being used
			usedVariables.add(parameterName);

			// Skip if the parameter is illegally named.
			if (!isSafeName(parameterName))
				continue;

			// Skip parameters with types that aren't accessible in the workspace.
			String descriptor = parameterVariable.getDescriptor();
			if (isMissingType(descriptor))
				continue;

			// Append the parameter.
			NameType varInfo = getInfo(parameterName, descriptor);
			parameterVarIndex += varInfo.size();
			code.append(varInfo.className()).append(' ').append(varInfo.name());
			if (i < parameterCount - 1) code.append(", ");
		}
		for (LocalVariable variable : methodVariables) {
			String name = variable.getName();

			// Skip illegal named variables and the implicit 'this'
			if (!isSafeName(name) || name.equals("this"))
				continue;

			// Skip if we already included the parameter in the loop above.
			boolean hasPriorParameters = !usedVariables.isEmpty();
			if (!usedVariables.add(name))
				continue;

			// Skip parameters with types that aren't accessible in the workspace.
			String descriptor = variable.getDescriptor();
			if (isMissingType(descriptor))
				continue;

			// Append the parameter.
			NameType varInfo = getInfo(name, descriptor);
			if (hasPriorParameters)
				code.append(", ");
			code.append(varInfo.className()).append(' ').append(varInfo.name());
		}

		// If we skipped the last parameter for some reason we need to remove the trailing ', ' before closing
		// off the parameters section.
		if (code.substring(code.length() - 2).endsWith(", "))
			code.setLength(code.length() - 2);

		// Close off declaration and add a throws so the user doesn't need to specify try-catch.
		code.append(") throws Throwable { " + ExpressionCompiler.EXPR_MARKER + " \n");
		code.append(expression);
		code.append("}\n");
	}
@param code
		Class code to append method definition to.
@param expression
		User-defined expression.

@throws ExpressionCompileException
		When the expression hosting method could not be fully generated.
recaf-core/src/main/java/software/coley/recaf/services/compile/stub/ExpressionHostingClassStubGenerator.java