public CompletableFuture handle()

in com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/EvaluateRequestHandler.java [60:179]


    public CompletableFuture<Response> handle(Command command, Arguments arguments, Response response, IDebugAdapterContext context) {
        EvaluateArguments evalArguments = (EvaluateArguments) arguments;
        final boolean showStaticVariables = DebugSettings.getCurrent().showStaticVariables;
        Map<String, Object> options = context.getVariableFormatter().getDefaultOptions();
        VariableUtils.applyFormatterOptions(options, evalArguments.format != null && evalArguments.format.hex);
        String expression = evalArguments.expression;

        if (StringUtils.isBlank(expression)) {
            throw new CompletionException(AdapterUtils.createUserErrorDebugException(
                "Failed to evaluate. Reason: Empty expression cannot be evaluated.",
                ErrorCode.EVALUATION_COMPILE_ERROR));
        }
        StackFrameReference stackFrameReference = (StackFrameReference) context.getRecyclableIdPool().getObjectById(evalArguments.frameId);
        if (stackFrameReference == null) {
            // stackFrameReference is null means the given thread is running
            throw new CompletionException(AdapterUtils.createUserErrorDebugException(
                    "Evaluation failed because the thread is not suspended.",
                    ErrorCode.EVALUATE_NOT_SUSPENDED_THREAD));
        }

        return CompletableFuture.supplyAsync(() -> {
            IEvaluationProvider engine = context.getProvider(IEvaluationProvider.class);
            try {
                Value value = engine.evaluate(expression, stackFrameReference.getThread(), stackFrameReference.getDepth()).get();
                IVariableFormatter variableFormatter = context.getVariableFormatter();
                if (value instanceof VoidValue) {
                    response.body = new Responses.EvaluateResponseBody(value.toString(), 0, "<void>", 0);
                    return response;
                }
                long threadId = stackFrameReference.getThread().uniqueID();
                if (value instanceof ObjectReference) {
                    VariableProxy varProxy = new VariableProxy(stackFrameReference.getThread(), "eval", value, null, expression);
                    int indexedVariables = -1;
                    Value sizeValue = null;
                    if (value instanceof ArrayReference) {
                        indexedVariables = ((ArrayReference) value).length();
                    } else if (value instanceof ObjectReference && DebugSettings.getCurrent().showLogicalStructure && engine != null) {
                        try {
                            JavaLogicalStructure structure = JavaLogicalStructureManager.getLogicalStructure((ObjectReference) value);
                            if (structure != null && structure.getSizeExpression() != null) {
                                sizeValue = structure.getSize((ObjectReference) value, stackFrameReference.getThread(), engine);
                                if (sizeValue != null && sizeValue instanceof IntegerValue) {
                                    indexedVariables = ((IntegerValue) sizeValue).value();
                                }
                            }
                        } catch (Exception e) {
                            logger.log(Level.INFO, "Failed to get the logical size of the variable", e);
                        }
                    }
                    int referenceId = 0;
                    if (indexedVariables > 0 || (indexedVariables < 0 && value instanceof ObjectReference)) {
                        referenceId = context.getRecyclableIdPool().addObject(threadId, varProxy);
                    }

                    boolean hasErrors = false;
                    String valueString = null;
                    try {
                        valueString = variableFormatter.valueToString(value, options);
                    } catch (OutOfMemoryError e) {
                        hasErrors = true;
                        logger.log(Level.SEVERE, "Failed to convert the value of a large object to a string", e);
                        valueString = "<Unable to display the value of a large object>";
                    }  catch (Exception e) {
                        hasErrors = true;
                        logger.log(Level.SEVERE, "Failed to resolve the variable value", e);
                        valueString = "<Failed to resolve the variable value due to \"" + e.getMessage() + "\">";
                    }

                    String detailsString = null;
                    if (hasErrors) {
                        // If failed to resolve the variable value, skip the details info as well.
                    } else if (sizeValue != null) {
                        detailsString = "size=" + variableFormatter.valueToString(sizeValue, options);
                    } else if (DebugSettings.getCurrent().showToString) {
                        try {
                            detailsString = VariableDetailUtils.formatDetailsValue(value, stackFrameReference.getThread(), variableFormatter, options, engine);
                        } catch (OutOfMemoryError e) {
                            logger.log(Level.SEVERE, "Failed to compute the toString() value of a large object", e);
                            detailsString = "<Unable to display the details of a large object>";
                        } catch (Exception e) {
                            logger.log(Level.SEVERE, "Failed to compute the toString() value", e);
                            detailsString = "<Failed to resolve the variable details due to \"" + e.getMessage() + "\">";
                        }
                    }

                    if ("clipboard".equals(evalArguments.context) && detailsString != null) {
                        response.body = new Responses.EvaluateResponseBody(detailsString, -1, "String", 0);
                    } else {
                        String typeString = "";
                        try {
                            typeString = variableFormatter.typeToString(value == null ? null : value.type(), options);
                        } catch (Exception e) {
                            logger.log(Level.SEVERE, "Failed to resolve the variable type", e);
                            typeString = "";
                        }
                        response.body = new Responses.EvaluateResponseBody((detailsString == null) ? valueString : valueString + " " + detailsString,
                                referenceId, typeString, Math.max(indexedVariables, 0));
                    }
                    return response;
                }
                // for primitive value
                response.body = new Responses.EvaluateResponseBody(variableFormatter.valueToString(value, options), 0,
                        variableFormatter.typeToString(value == null ? null : value.type(), options), 0);
                return response;
            } catch (InterruptedException | ExecutionException e) {
                Throwable cause = e;
                if (e instanceof ExecutionException && e.getCause() != null) {
                    cause = e.getCause();
                }

                if (cause instanceof DebugException) {
                    throw new CompletionException(cause);
                }
                throw AdapterUtils.createCompletionException(
                    String.format("Cannot evaluate because of %s.", cause.toString()),
                    ErrorCode.EVALUATE_FAILURE,
                    cause);
            }
        });
    }