Example #1
0
 /// <summary>
 /// This method is called by the debug engine to compile an expression that the user wants
 /// to evaluate.  Before the call, we have the text of the expression and information about
 /// the context we want to evaluate in (code location, evaluation flags, etc.).  The result
 /// of the call is a &quot;query&quot; containing IL the debugger will execute to get the
 /// result of the expression.
 /// </summary>
 /// <param name="expression">This is the raw expression to compile</param>
 /// <param name="instructionAddress">Instruction address or code location to use as the
 /// context of the compilation.</param>
 /// <param name="inspectionContext">Context of the evaluation.  This contains options/flags
 /// to be used during compilation. It also contains the InspectionSession.  The inspection
 /// session is the object that provides lifetime management for our objects.  When the user
 /// steps or continues the process, the debug engine will dispose of the inspection session</param>
 /// <param name="error">[Out] If the there are any compile errors, this parameter is set to
 /// the error message to display to the user</param>
 /// <param name="result">[Out] If compilation was successful, this is the output query.</param>
 void IDkmClrExpressionCompiler.CompileExpression(
     DkmLanguageExpression expression,
     DkmClrInstructionAddress instructionAddress,
     DkmInspectionContext inspectionContext,
     out string error,
     out DkmCompiledClrInspectionQuery result)
 {
     error  = null;
     result = null;
     expression.CompileExpression(instructionAddress, inspectionContext, out error, out result);
     return;
 }
        /// <summary>
        /// This method is called by the debug engine to compile an expression that the user wants
        /// to evaluate.  Before the call, we have the text of the expression and information about
        /// the context we want to evaluate in (code location, evaluation flags, etc.).  The result
        /// of the call is a &quot;query&quot; containing IL the debugger will execute to get the
        /// result of the expression.
        /// </summary>
        /// <param name="expression">This is the raw expression to compile</param>
        /// <param name="instructionAddress">Instruction address or code location to use as the
        /// context of the compilation.</param>
        /// <param name="inspectionContext">Context of the evaluation.  This contains options/flags
        /// to be used during compilation. It also contains the InspectionSession.  The inspection
        /// session is the object that provides lifetime management for our objects.  When the user
        /// steps or continues the process, the debug engine will dispose of the inspection session</param>
        /// <param name="error">[Out] If the there are any compile errors, this parameter is set to
        /// the error message to display to the user</param>
        /// <param name="result">[Out] If compilation was successful, this is the output query.</param>
        void IDkmClrExpressionCompiler.CompileExpression(
            DkmLanguageExpression expression,
            DkmClrInstructionAddress instructionAddress,
            DkmInspectionContext inspectionContext,
            out string error,
            out DkmCompiledClrInspectionQuery result)
        {
            error  = null;
            result = null;
            bool   changed      = false;
            string originalExpr = expression.Text;
            // We use a trick to change the Text when sending it to C#, by retrieveing the field info.
            // This field has a property get but not a property set.
            var fi = typeof(DkmLanguageExpression).GetField("m_Text", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

            if (fi != null)
            {
                var newexpr = originalExpr;
                if (expression.Text.StartsWith("SELF", System.StringComparison.OrdinalIgnoreCase))
                {
                    changed = true;
                    newexpr = "this" + originalExpr.Substring(4);
                }
                else if (expression.Text.StartsWith("SUPER", System.StringComparison.OrdinalIgnoreCase))
                {
                    changed = true;
                    newexpr = "base" + originalExpr.Substring(5);
                }
                if (newexpr.Contains(":"))
                {
                    newexpr = newexpr.Replace(':', '.');
                    changed = true;
                }
                // check for literal array
                //var lbrkt = newexpr.IndexOf('[');
                //var rbrkt = newexpr.IndexOf(']');
                //if (lbrkt > 0 && rbrkt > 0 && lbrkt < rbrkt)
                //{
                //    newexpr = AdjustArrayIndices(newexpr, ref changed);
                //}
                if (changed && fi != null)
                {
                    fi.SetValue(expression, newexpr);
                }
            }
            expression.CompileExpression(instructionAddress, inspectionContext, out error, out result);
            if (changed && fi != null)
            {
                fi.SetValue(expression, originalExpr);
            }
            return;
        }