[Monodevelop-patches-list] r2282 - in trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn: . Gui
Chris Toshok
toshok at mono-cvs.ximian.com
Tue Mar 1 18:58:20 EST 2005
Author: toshok
Date: 2005-03-01 18:58:20 -0500 (Tue, 01 Mar 2005)
New Revision: 2282
Added:
trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpExpressionParser.cs
trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpExpressionParser.jay
trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpTokenizer.cs
trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/EvaluationContext.cs
trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Expression.cs
trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/MyTextReader.cs
Modified:
trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/ChangeLog
trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/DebuggingService.cs
trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Gui/DebuggerVariablePad.cs
trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Makefile.am
Log:
2005-03-01 Chris Toshok <toshok at ximian.com>
* Gui/DebuggerVariablePad.cs (DebuggerVariablePad.add_member):
strip out the part of add_struct that adds individual fields and
implement all the DebuggerBrowsableAttribute handling.
(DebuggerVariablePad.add_struct): display both fields and
properties.
(DebuggerVariablePad.GetDebuggerBrowsableAttribute): returns the
first DebuggerBrowsable attribute for a given ITargetMemberInfo,
if there are any.
(DebuggerVariablePad.GetDebuggerDisplayAttribute): returns the
first DebuggerDisplay attribute for a given ITargetObject, if
there are any.
(DebuggerVariablePad.EvaluateDebuggerDisplay): given the
DebuggerDisplay attribute's value, evaluate any nested
{expressions} and convert them all to strings.
(DebuggerVariablePad.add_object): if it's a struct or class, add
the DebuggerDisplay if there is one.
* DebuggingService.cs (MainThread): add a getter for this, so we
can grab a thread with which to evaluate expressions in
DebuggerDisplayAttributes.
* Makefile.am (FILES): add stripped down files from the debugger
source - EvaluationContext.cs (formerly ScriptingContext),
Expression.cs, MyTextReader.cs, CSharpTokenizer.cs, and
CSharpExpressionParser.cs.
Added: trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpExpressionParser.cs
===================================================================
--- trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpExpressionParser.cs 2005-02-28 23:54:16 UTC (rev 2281)
+++ trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpExpressionParser.cs 2005-03-01 23:58:20 UTC (rev 2282)
@@ -0,0 +1,753 @@
+// created by jay 0.7 (c) 1998 Axel.Schreiner at informatik.uni-osnabrueck.de
+
+#line 2 "CSharpExpressionParser.jay"
+using System.Text;
+using System.IO;
+using System.Collections;
+using System;
+
+namespace Debugger.Frontend
+{
+#if NET_2_0
+ public class CSharpExpressionParser
+ {
+ EvaluationContext current_context;
+ MyTextReader reader;
+ Tokenizer lexer;
+
+ protected bool yacc_verbose_flag = false;
+
+ public bool Verbose {
+ set {
+ yacc_verbose_flag = value;
+ }
+
+ get {
+ return yacc_verbose_flag;
+ }
+ }
+
+#line default
+
+ /** simplified error message.
+ @see <a href="#yyerror(java.lang.String, java.lang.String[])">yyerror</a>
+ */
+ public void yyerror (string message) {
+ yyerror(message, null);
+ }
+
+ /** (syntax) error message.
+ Can be overwritten to control message format.
+ @param message text to be displayed.
+ @param expected vector of acceptable tokens, if available.
+ */
+ public void yyerror (string message, string[] expected) {
+ if ((expected != null) && (expected.Length > 0)) {
+ System.Console.Write (message+", expecting");
+ for (int n = 0; n < expected.Length; ++ n)
+ System.Console.Write (" "+expected[n]);
+ System.Console.WriteLine ();
+ } else
+ System.Console.WriteLine (message);
+ }
+
+ /** debugging support, requires the package jay.yydebug.
+ Set to null to suppress debugging messages.
+ */
+ internal yydebug.yyDebug debug;
+
+ protected static int yyFinal = 13;
+ public static string [] yyRule = {
+ "$accept : parse_expression",
+ "parse_expression : primary_expression",
+ "primary_expression : expression",
+ "primary_expression : expression ASSIGN expression",
+ "expression : NUMBER",
+ "expression : INTEGER",
+ "expression : STRING",
+ "expression : THIS",
+ "expression : CATCH",
+ "expression : BASE DOTDOT IDENTIFIER",
+ "expression : BASE DOT IDENTIFIER",
+ "expression : variable_or_type_name",
+ "expression : PERCENT IDENTIFIER",
+ "expression : STAR expression",
+ "expression : AMPERSAND expression",
+ "expression : expression OPEN_BRACKET expression CLOSE_BRACKET",
+ "expression : expression OPEN_PARENS argument_list CLOSE_PARENS",
+ "expression : NEW variable_or_type_name OPEN_PARENS argument_list CLOSE_PARENS",
+ "expression : OPEN_PARENS variable_or_type_name CLOSE_PARENS expression",
+ "expression : OPEN_PARENS expression CLOSE_PARENS",
+ "argument_list :",
+ "argument_list : argument_list_0",
+ "argument_list_0 : expression",
+ "argument_list_0 : argument_list_0 COMMA expression",
+ "variable_or_type_name : IDENTIFIER",
+ "variable_or_type_name : expression DOT IDENTIFIER",
+ "variable_or_type_name : expression DOTDOT IDENTIFIER",
+ "variable_or_type_name : expression MINUS OP_GT IDENTIFIER",
+ };
+ protected static string [] yyNames = {
+ "end-of-file",null,null,null,null,null,null,null,null,null,null,null,
+ null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+ null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+ null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+ null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+ null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+ null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+ null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+ null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+ null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+ null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+ null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+ null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+ null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+ null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+ null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+ null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+ null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+ null,null,null,null,null,null,null,"QUIT","EOF","NONE","ERROR",
+ "IDENTIFIER","INTEGER","NUMBER","STRING","HASH","AT","PERCENT",
+ "DOLLAR","DOT","DOTDOT","BANG","COMMA","ASSIGN","STAR","PLUS","MINUS",
+ "DIV","OPEN_PARENS","CLOSE_PARENS","OPEN_BRACKET","CLOSE_BRACKET",
+ "OP_LT","OP_GT","COLON","AMPERSAND","LENGTH","LOWER","UPPER","NEW",
+ "THIS","BASE","CATCH",
+ };
+
+ /** index-checked interface to yyNames[].
+ @param token single character or %token value.
+ @return token name or [illegal] or [unknown].
+ */
+ public static string yyname (int token) {
+ if ((token < 0) || (token > yyNames.Length)) return "[illegal]";
+ string name;
+ if ((name = yyNames[token]) != null) return name;
+ return "[unknown]";
+ }
+
+ /** computes list of expected tokens on error by tracing the tables.
+ @param state for which to compute the list.
+ @return list of token names.
+ */
+ protected string[] yyExpecting (int state) {
+ int token, n, len = 0;
+ bool[] ok = new bool[yyNames.Length];
+
+ if ((n = yySindex[state]) != 0)
+ for (token = n < 0 ? -n : 0;
+ (token < yyNames.Length) && (n+token < yyTable.Length); ++ token)
+ if (yyCheck[n+token] == token && !ok[token] && yyNames[token] != null) {
+ ++ len;
+ ok[token] = true;
+ }
+ if ((n = yyRindex[state]) != 0)
+ for (token = n < 0 ? -n : 0;
+ (token < yyNames.Length) && (n+token < yyTable.Length); ++ token)
+ if (yyCheck[n+token] == token && !ok[token] && yyNames[token] != null) {
+ ++ len;
+ ok[token] = true;
+ }
+
+ string [] result = new string[len];
+ for (n = token = 0; n < len; ++ token)
+ if (ok[token]) result[n++] = yyNames[token];
+ return result;
+ }
+
+ /** the generated parser, with debugging messages.
+ Maintains a state and a value stack, currently with fixed maximum size.
+ @param yyLex scanner.
+ @param yydebug debug message writer implementing yyDebug, or null.
+ @return result of the last reduction, if any.
+ @throws yyException on irrecoverable parse error.
+ */
+ internal Object yyparse (yyParser.yyInput yyLex, Object yyd)
+ {
+ this.debug = (yydebug.yyDebug)yyd;
+ return yyparse(yyLex);
+ }
+
+ /** initial size and increment of the state/value stack [default 256].
+ This is not final so that it can be overwritten outside of invocations
+ of yyparse().
+ */
+ protected int yyMax;
+
+ /** executed at the beginning of a reduce action.
+ Used as $$ = yyDefault($1), prior to the user-specified action, if any.
+ Can be overwritten to provide deep copy, etc.
+ @param first value for $1, or null.
+ @return first.
+ */
+ protected Object yyDefault (Object first) {
+ return first;
+ }
+
+ /** the generated parser.
+ Maintains a state and a value stack, currently with fixed maximum size.
+ @param yyLex scanner.
+ @return result of the last reduction, if any.
+ @throws yyException on irrecoverable parse error.
+ */
+ internal Object yyparse (yyParser.yyInput yyLex)
+ {
+ if (yyMax <= 0) yyMax = 256; // initial size
+ int yyState = 0; // state stack ptr
+ int [] yyStates = new int[yyMax]; // state stack
+ Object yyVal = null; // value stack ptr
+ Object [] yyVals = new Object[yyMax]; // value stack
+ int yyToken = -1; // current input
+ int yyErrorFlag = 0; // #tks to shift
+
+ int yyTop = 0;
+ goto skip;
+ yyLoop:
+ yyTop++;
+ skip:
+ for (;; ++ yyTop) {
+ if (yyTop >= yyStates.Length) { // dynamically increase
+ int[] i = new int[yyStates.Length+yyMax];
+ yyStates.CopyTo (i, 0);
+ yyStates = i;
+ Object[] o = new Object[yyVals.Length+yyMax];
+ yyVals.CopyTo (o, 0);
+ yyVals = o;
+ }
+ yyStates[yyTop] = yyState;
+ yyVals[yyTop] = yyVal;
+ if (debug != null) debug.push(yyState, yyVal);
+
+ yyDiscarded: for (;;) { // discarding a token does not change stack
+ int yyN;
+ if ((yyN = yyDefRed[yyState]) == 0) { // else [default] reduce (yyN)
+ if (yyToken < 0) {
+ yyToken = yyLex.advance() ? yyLex.token() : 0;
+ if (debug != null)
+ debug.lex(yyState, yyToken, yyname(yyToken), yyLex.value());
+ }
+ if ((yyN = yySindex[yyState]) != 0 && ((yyN += yyToken) >= 0)
+ && (yyN < yyTable.Length) && (yyCheck[yyN] == yyToken)) {
+ if (debug != null)
+ debug.shift(yyState, yyTable[yyN], yyErrorFlag-1);
+ yyState = yyTable[yyN]; // shift to yyN
+ yyVal = yyLex.value();
+ yyToken = -1;
+ if (yyErrorFlag > 0) -- yyErrorFlag;
+ goto yyLoop;
+ }
+ if ((yyN = yyRindex[yyState]) != 0 && (yyN += yyToken) >= 0
+ && yyN < yyTable.Length && yyCheck[yyN] == yyToken)
+ yyN = yyTable[yyN]; // reduce (yyN)
+ else
+ switch (yyErrorFlag) {
+
+ case 0:
+ yyerror("syntax error", yyExpecting(yyState));
+ if (debug != null) debug.error("syntax error");
+ goto case 1;
+ case 1: case 2:
+ yyErrorFlag = 3;
+ do {
+ if ((yyN = yySindex[yyStates[yyTop]]) != 0
+ && (yyN += Token.yyErrorCode) >= 0 && yyN < yyTable.Length
+ && yyCheck[yyN] == Token.yyErrorCode) {
+ if (debug != null)
+ debug.shift(yyStates[yyTop], yyTable[yyN], 3);
+ yyState = yyTable[yyN];
+ yyVal = yyLex.value();
+ goto yyLoop;
+ }
+ if (debug != null) debug.pop(yyStates[yyTop]);
+ } while (-- yyTop >= 0);
+ if (debug != null) debug.reject();
+ throw new yyParser.yyException("irrecoverable syntax error");
+
+ case 3:
+ if (yyToken == 0) {
+ if (debug != null) debug.reject();
+ throw new yyParser.yyException("irrecoverable syntax error at end-of-file");
+ }
+ if (debug != null)
+ debug.discard(yyState, yyToken, yyname(yyToken),
+ yyLex.value());
+ yyToken = -1;
+ goto yyDiscarded; // leave stack alone
+ }
+ }
+ int yyV = yyTop + 1-yyLen[yyN];
+ if (debug != null)
+ debug.reduce(yyState, yyStates[yyV-1], yyN, yyRule[yyN], yyLen[yyN]);
+ yyVal = yyDefault(yyV > yyTop ? null : yyVals[yyV]);
+ switch (yyN) {
+case 1:
+#line 75 "CSharpExpressionParser.jay"
+ {
+ return yyVals[0+yyTop];
+ }
+ break;
+case 3:
+#line 83 "CSharpExpressionParser.jay"
+ {
+ yyVal = new AssignmentExpression ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
+ }
+ break;
+case 4:
+#line 90 "CSharpExpressionParser.jay"
+ {
+ yyVal = new NumberExpression ((long) yyVals[0+yyTop]);
+ }
+ break;
+case 5:
+#line 94 "CSharpExpressionParser.jay"
+ {
+ yyVal = new NumberExpression ((int) yyVals[0+yyTop]);
+ }
+ break;
+case 6:
+#line 98 "CSharpExpressionParser.jay"
+ {
+ yyVal = new StringExpression ((string) yyVals[0+yyTop]);
+ }
+ break;
+case 7:
+#line 102 "CSharpExpressionParser.jay"
+ {
+ yyVal = new ThisExpression ();
+ }
+ break;
+case 8:
+#line 106 "CSharpExpressionParser.jay"
+ {
+ // yyVal = new CatchExpression ();
+ }
+ break;
+case 9:
+#line 110 "CSharpExpressionParser.jay"
+ {
+ yyVal = new MemberAccessExpression (new BaseExpression (), "." + ((string) yyVals[0+yyTop]));
+ }
+ break;
+case 10:
+#line 114 "CSharpExpressionParser.jay"
+ {
+ yyVal = new MemberAccessExpression (new BaseExpression (), (string) yyVals[0+yyTop]);
+ }
+ break;
+case 12:
+#line 119 "CSharpExpressionParser.jay"
+ {
+ // yyVal = new RegisterExpression ((string) yyVals[0+yyTop], 0);
+ }
+ break;
+case 13:
+#line 123 "CSharpExpressionParser.jay"
+ {
+ yyVal = new PointerDereferenceExpression ((Expression) yyVals[0+yyTop], false);
+ }
+ break;
+case 14:
+#line 127 "CSharpExpressionParser.jay"
+ {
+ yyVal = new AddressOfExpression ((Expression) yyVals[0+yyTop]);
+ }
+ break;
+case 15:
+#line 131 "CSharpExpressionParser.jay"
+ {
+ yyVal = new ArrayAccessExpression ((Expression) yyVals[-3+yyTop], (Expression) yyVals[-1+yyTop]);
+ }
+ break;
+case 16:
+#line 135 "CSharpExpressionParser.jay"
+ {
+ yyVal = new InvocationExpression ((Expression) yyVals[-3+yyTop], ((Expression []) yyVals[-1+yyTop]));
+ }
+ break;
+case 17:
+#line 139 "CSharpExpressionParser.jay"
+ {
+ yyVal = new NewExpression ((Expression) yyVals[-3+yyTop], ((Expression []) yyVals[-1+yyTop]));
+ }
+ break;
+case 18:
+#line 143 "CSharpExpressionParser.jay"
+ {
+ yyVal = new CastExpression ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
+ }
+ break;
+case 19:
+#line 147 "CSharpExpressionParser.jay"
+ {
+ yyVal = yyVals[-1+yyTop];
+ }
+ break;
+case 20:
+#line 154 "CSharpExpressionParser.jay"
+ {
+ yyVal = new Expression [0];
+ }
+ break;
+case 21:
+#line 158 "CSharpExpressionParser.jay"
+ {
+ Expression[] args = new Expression [((ArrayList) yyVals[0+yyTop]).Count];
+ ((ArrayList) yyVals[0+yyTop]).CopyTo (args, 0);
+
+ yyVal = args;
+ }
+ break;
+case 22:
+#line 168 "CSharpExpressionParser.jay"
+ {
+ ArrayList args = new ArrayList ();
+ args.Add (yyVals[0+yyTop]);
+
+ yyVal = args;
+ }
+ break;
+case 23:
+#line 175 "CSharpExpressionParser.jay"
+ {
+ ArrayList args = (ArrayList) yyVals[-2+yyTop];
+ args.Add (yyVals[0+yyTop]);
+
+ yyVal = args;
+ }
+ break;
+case 24:
+#line 185 "CSharpExpressionParser.jay"
+ {
+ yyVal = new SimpleNameExpression ((string) yyVals[0+yyTop]);
+ }
+ break;
+case 25:
+#line 189 "CSharpExpressionParser.jay"
+ {
+ yyVal = new MemberAccessExpression ((Expression) yyVals[-2+yyTop], (string) yyVals[0+yyTop]);
+ }
+ break;
+case 26:
+#line 193 "CSharpExpressionParser.jay"
+ {
+ yyVal = new MemberAccessExpression ((Expression) yyVals[-2+yyTop], "." + (string) yyVals[0+yyTop]);
+ }
+ break;
+case 27:
+#line 197 "CSharpExpressionParser.jay"
+ {
+ Expression expr = new PointerDereferenceExpression ((Expression) yyVals[-3+yyTop], true);
+ yyVal = new MemberAccessExpression (expr, (string) yyVals[0+yyTop]);
+ }
+ break;
+#line default
+ }
+ yyTop -= yyLen[yyN];
+ yyState = yyStates[yyTop];
+ int yyM = yyLhs[yyN];
+ if (yyState == 0 && yyM == 0) {
+ if (debug != null) debug.shift(0, yyFinal);
+ yyState = yyFinal;
+ if (yyToken < 0) {
+ yyToken = yyLex.advance() ? yyLex.token() : 0;
+ if (debug != null)
+ debug.lex(yyState, yyToken,yyname(yyToken), yyLex.value());
+ }
+ if (yyToken == 0) {
+ if (debug != null) debug.accept(yyVal);
+ return yyVal;
+ }
+ goto yyLoop;
+ }
+ if (((yyN = yyGindex[yyM]) != 0) && ((yyN += yyState) >= 0)
+ && (yyN < yyTable.Length) && (yyCheck[yyN] == yyState))
+ yyState = yyTable[yyN];
+ else
+ yyState = yyDgoto[yyM];
+ if (debug != null) debug.shift(yyStates[yyTop], yyState);
+ goto yyLoop;
+ }
+ }
+ }
+
+ static short [] yyLhs = { -1,
+ 0, 1, 1, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 4,
+ 4, 5, 5, 3, 3, 3, 3,
+ };
+ static short [] yyLen = { 2,
+ 1, 1, 3, 1, 1, 1, 1, 1, 3, 3,
+ 1, 2, 2, 2, 4, 4, 5, 4, 3, 0,
+ 1, 1, 3, 1, 3, 3, 4,
+ };
+ static short [] yyDefRed = { 0,
+ 24, 5, 4, 6, 0, 0, 0, 0, 0, 7,
+ 0, 8, 0, 1, 0, 11, 12, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 19, 0, 0, 10, 9, 25, 26, 0, 0,
+ 0, 0, 0, 0, 0, 0, 27, 16, 0, 15,
+ 17, 0,
+ };
+ protected static short [] yyDgoto = { 13,
+ 14, 41, 16, 42, 43,
+ };
+ protected static short [] yySindex = { -246,
+ 0, 0, 0, 0, -255, -246, -246, -246, -246, 0,
+ -245, 0, 0, 0, -215, 0, 0, -198, -210, -253,
+ -198, -198, -256, -232, -230, -227, -225, -246, -243, -246,
+ -246, 0, -246, -246, 0, 0, 0, 0, -198, -224,
+ -198, -241, -223, -228, -198, -222, 0, 0, -246, 0,
+ 0, -198,
+ };
+ protected static short [] yyRindex = { 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 47, 0, 0, 1, 0, -195,
+ 4, 0, -257, 0, 0, 0, 0, 0, 0, -217,
+ 0, 0, 0, -217, 0, 0, 0, 0, 56, 0,
+ -272, 0, -212, 0, 14, 0, 0, 0, 0, 0,
+ 0, -252,
+ };
+ protected static short [] yyGindex = { 0,
+ 0, 2, -4, 30, 0,
+ };
+ protected static short [] yyTable = { 22,
+ 13, 15, 20, 14, 23, 17, 22, 18, 19, 21,
+ 22, 11, 11, 18, 1, 2, 3, 4, 11, 23,
+ 5, 34, 11, 24, 25, 33, 23, 6, 35, 39,
+ 36, 7, 44, 37, 45, 38, 47, 48, 8, 40,
+ 26, 27, 9, 10, 11, 12, 2, 29, 49, 30,
+ 52, 31, 50, 26, 27, 3, 51, 28, 26, 27,
+ 29, 20, 30, 46, 31, 29, 21, 30, 32, 31,
+ 26, 27, 0, 11, 11, 0, 0, 29, 0, 30,
+ 11, 31, 11, 0, 11, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 13, 13, 0, 14, 14, 0, 0, 13,
+ 0, 13, 14, 0, 14, 18, 18, 0, 0, 0,
+ 0, 0, 18, 0, 18,
+ };
+ protected static short [] yyCheck = { 272,
+ 0, 0, 7, 0, 9, 261, 279, 6, 7, 8,
+ 9, 269, 270, 0, 261, 262, 263, 264, 276, 272,
+ 267, 278, 280, 269, 270, 279, 279, 274, 261, 28,
+ 261, 278, 31, 261, 33, 261, 261, 279, 285, 283,
+ 269, 270, 289, 290, 291, 292, 0, 276, 272, 278,
+ 49, 280, 281, 269, 270, 0, 279, 273, 269, 270,
+ 276, 279, 278, 34, 280, 276, 279, 278, 279, 280,
+ 269, 270, -1, 269, 270, -1, -1, 276, -1, 278,
+ 276, 280, 278, -1, 280, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 272, 273, -1, 272, 273, -1, -1, 279,
+ -1, 281, 279, -1, 281, 272, 273, -1, -1, -1,
+ -1, -1, 279, -1, 281,
+ };
+
+#line 204 "CSharpExpressionParser.jay"
+
+public CSharpExpressionParser (EvaluationContext context, string name)
+{
+ this.reader = new MyTextReader ();
+ this.current_context = context;
+
+ lexer = new Tokenizer (context, reader, name);
+}
+
+public Expression Parse (string text)
+{
+ try {
+ reader.Text = text;
+ lexer.restart ();
+ if (yacc_verbose_flag)
+ return (Expression) yyparse (lexer, new yydebug.yyDebugSimple ());
+ else
+ return (Expression) yyparse (lexer);
+ } catch (Exception e){
+ // Please do not remove this, it is used during debugging
+ // of the grammar
+ //
+// current_context.Error (lexer.location + " : Parsing error ");
+// current_context.Error (e.ToString ());
+ return null;
+ }
+}
+
+/* end end end */
+}
+#line default
+namespace yydebug {
+ using System;
+ internal interface yyDebug {
+ void push (int state, Object value);
+ void lex (int state, int token, string name, Object value);
+ void shift (int from, int to, int errorFlag);
+ void pop (int state);
+ void discard (int state, int token, string name, Object value);
+ void reduce (int from, int to, int rule, string text, int len);
+ void shift (int from, int to);
+ void accept (Object value);
+ void error (string message);
+ void reject ();
+ }
+
+ class yyDebugSimple : yyDebug {
+ void println (string s){
+ Console.WriteLine (s);
+ }
+
+ public void push (int state, Object value) {
+ println ("push\tstate "+state+"\tvalue "+value);
+ }
+
+ public void lex (int state, int token, string name, Object value) {
+ println("lex\tstate "+state+"\treading "+name+"\tvalue "+value);
+ }
+
+ public void shift (int from, int to, int errorFlag) {
+ switch (errorFlag) {
+ default: // normally
+ println("shift\tfrom state "+from+" to "+to);
+ break;
+ case 0: case 1: case 2: // in error recovery
+ println("shift\tfrom state "+from+" to "+to
+ +"\t"+errorFlag+" left to recover");
+ break;
+ case 3: // normally
+ println("shift\tfrom state "+from+" to "+to+"\ton error");
+ break;
+ }
+ }
+
+ public void pop (int state) {
+ println("pop\tstate "+state+"\ton error");
+ }
+
+ public void discard (int state, int token, string name, Object value) {
+ println("discard\tstate "+state+"\ttoken "+name+"\tvalue "+value);
+ }
+
+ public void reduce (int from, int to, int rule, string text, int len) {
+ println("reduce\tstate "+from+"\tuncover "+to
+ +"\trule ("+rule+") "+text);
+ }
+
+ public void shift (int from, int to) {
+ println("goto\tfrom state "+from+" to "+to);
+ }
+
+ public void accept (Object value) {
+ println("accept\tvalue "+value);
+ }
+
+ public void error (string message) {
+ println("error\t"+message);
+ }
+
+ public void reject () {
+ println("reject");
+ }
+
+ }
+}
+// %token constants
+ class Token {
+ public const int QUIT = 257;
+ public const int EOF = 258;
+ public const int NONE = 259;
+ public const int ERROR = 260;
+ public const int IDENTIFIER = 261;
+ public const int INTEGER = 262;
+ public const int NUMBER = 263;
+ public const int STRING = 264;
+ public const int HASH = 265;
+ public const int AT = 266;
+ public const int PERCENT = 267;
+ public const int DOLLAR = 268;
+ public const int DOT = 269;
+ public const int DOTDOT = 270;
+ public const int BANG = 271;
+ public const int COMMA = 272;
+ public const int ASSIGN = 273;
+ public const int STAR = 274;
+ public const int PLUS = 275;
+ public const int MINUS = 276;
+ public const int DIV = 277;
+ public const int OPEN_PARENS = 278;
+ public const int CLOSE_PARENS = 279;
+ public const int OPEN_BRACKET = 280;
+ public const int CLOSE_BRACKET = 281;
+ public const int OP_LT = 282;
+ public const int OP_GT = 283;
+ public const int COLON = 284;
+ public const int AMPERSAND = 285;
+ public const int LENGTH = 286;
+ public const int LOWER = 287;
+ public const int UPPER = 288;
+ public const int NEW = 289;
+ public const int THIS = 290;
+ public const int BASE = 291;
+ public const int CATCH = 292;
+ public const int yyErrorCode = 256;
+ }
+ namespace yyParser {
+ using System;
+ /** thrown for irrecoverable syntax errors and stack overflow.
+ */
+ internal class yyException : System.Exception {
+ public yyException (string message) : base (message) {
+ }
+ }
+
+ /** must be implemented by a scanner object to supply input to the parser.
+ */
+ internal interface yyInput {
+ /** move on to next token.
+ @return false if positioned beyond tokens.
+ @throws IOException on input error.
+ */
+ bool advance (); // throws java.io.IOException;
+ /** classifies current token.
+ Should not be called if advance() returned false.
+ @return current %token or single character.
+ */
+ int token ();
+ /** associated with current token.
+ Should not be called if advance() returned false.
+ @return value for token().
+ */
+ Object value ();
+ }
+ }
+#endif
+} // close outermost namespace, that MUST HAVE BEEN opened in the prolog
Added: trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpExpressionParser.jay
===================================================================
--- trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpExpressionParser.jay 2005-02-28 23:54:16 UTC (rev 2281)
+++ trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpExpressionParser.jay 2005-03-01 23:58:20 UTC (rev 2282)
@@ -0,0 +1,235 @@
+%{
+using System.Text;
+using System.IO;
+using System.Collections;
+using System;
+
+namespace Debugger.Frontend
+{
+#if NET_2_0
+ public class CSharpExpressionParser
+ {
+ EvaluationContext current_context;
+ MyTextReader reader;
+ Tokenizer lexer;
+
+ protected bool yacc_verbose_flag = false;
+
+ public bool Verbose {
+ set {
+ yacc_verbose_flag = value;
+ }
+
+ get {
+ return yacc_verbose_flag;
+ }
+ }
+
+%}
+
+%token QUIT
+%token EOF
+%token NONE // This token is never returned by our lexer
+%token ERROR // This is used not by the parser, but by the tokenizer.
+ // do not remove.
+
+%token IDENTIFIER
+%token INTEGER
+%token NUMBER
+%token STRING
+%token HASH
+%token AT
+%token PERCENT
+%token DOLLAR
+%token DOT
+%token DOTDOT
+%token BANG
+%token COMMA
+%token ASSIGN
+%token STAR
+%token PLUS
+%token MINUS
+%token DIV
+%token OPEN_PARENS
+%token CLOSE_PARENS
+%token OPEN_BRACKET
+%token CLOSE_BRACKET
+%token OP_LT
+%token OP_GT
+%token COLON
+%token AMPERSAND
+
+%token LENGTH
+%token LOWER
+%token UPPER
+
+%token NEW
+%token THIS
+%token BASE
+%token CATCH
+
+%start parse_expression
+%%
+
+parse_expression
+ : primary_expression
+ {
+ return $1;
+ }
+ ;
+
+primary_expression
+ : expression
+ | expression ASSIGN expression
+ {
+ $$ = new AssignmentExpression ((Expression) $1, (Expression) $3);
+ }
+ ;
+
+expression
+ : NUMBER
+ {
+ $$ = new NumberExpression ((long) $1);
+ }
+ | INTEGER
+ {
+ $$ = new NumberExpression ((int) $1);
+ }
+ | STRING
+ {
+ $$ = new StringExpression ((string) $1);
+ }
+ | THIS
+ {
+ $$ = new ThisExpression ();
+ }
+ | CATCH
+ {
+// $$ = new CatchExpression ();
+ }
+ | BASE DOTDOT IDENTIFIER
+ {
+ $$ = new MemberAccessExpression (new BaseExpression (), "." + ((string) $3));
+ }
+ | BASE DOT IDENTIFIER
+ {
+ $$ = new MemberAccessExpression (new BaseExpression (), (string) $3);
+ }
+ | variable_or_type_name
+ | PERCENT IDENTIFIER
+ {
+// $$ = new RegisterExpression ((string) $2, 0);
+ }
+ | STAR expression
+ {
+ $$ = new PointerDereferenceExpression ((Expression) $2, false);
+ }
+ | AMPERSAND expression
+ {
+ $$ = new AddressOfExpression ((Expression) $2);
+ }
+ | expression OPEN_BRACKET expression CLOSE_BRACKET
+ {
+ $$ = new ArrayAccessExpression ((Expression) $1, (Expression) $3);
+ }
+ | expression OPEN_PARENS argument_list CLOSE_PARENS
+ {
+ $$ = new InvocationExpression ((Expression) $1, ((Expression []) $3));
+ }
+ | NEW variable_or_type_name OPEN_PARENS argument_list CLOSE_PARENS
+ {
+ $$ = new NewExpression ((Expression) $2, ((Expression []) $4));
+ }
+ | OPEN_PARENS variable_or_type_name CLOSE_PARENS expression
+ {
+ $$ = new CastExpression ((Expression) $2, (Expression) $4);
+ }
+ | OPEN_PARENS expression CLOSE_PARENS
+ {
+ $$ = $2;
+ }
+ ;
+
+argument_list
+ : /* empty */
+ {
+ $$ = new Expression [0];
+ }
+ | argument_list_0
+ {
+ Expression[] args = new Expression [((ArrayList) $1).Count];
+ ((ArrayList) $1).CopyTo (args, 0);
+
+ $$ = args;
+ }
+ ;
+
+argument_list_0
+ : expression
+ {
+ ArrayList args = new ArrayList ();
+ args.Add ($1);
+
+ $$ = args;
+ }
+ | argument_list_0 COMMA expression
+ {
+ ArrayList args = (ArrayList) $1;
+ args.Add ($3);
+
+ $$ = args;
+ }
+ ;
+
+variable_or_type_name
+ : IDENTIFIER
+ {
+ $$ = new SimpleNameExpression ((string) $1);
+ }
+ | expression DOT IDENTIFIER
+ {
+ $$ = new MemberAccessExpression ((Expression) $1, (string) $3);
+ }
+ | expression DOTDOT IDENTIFIER
+ {
+ $$ = new MemberAccessExpression ((Expression) $1, "." + (string) $3);
+ }
+ | expression MINUS OP_GT IDENTIFIER
+ {
+ Expression expr = new PointerDereferenceExpression ((Expression) $1, true);
+ $$ = new MemberAccessExpression (expr, (string) $4);
+ }
+ ;
+
+%%
+
+public CSharpExpressionParser (EvaluationContext context, string name)
+{
+ this.reader = new MyTextReader ();
+ this.current_context = context;
+
+ lexer = new Tokenizer (context, reader, name);
+}
+
+public Expression Parse (string text)
+{
+ try {
+ reader.Text = text;
+ lexer.restart ();
+ if (yacc_verbose_flag)
+ return (Expression) yyparse (lexer, new yydebug.yyDebugSimple ());
+ else
+ return (Expression) yyparse (lexer);
+ } catch (Exception e){
+ // Please do not remove this, it is used during debugging
+ // of the grammar
+ //
+// current_context.Error (lexer.location + " : Parsing error ");
+// current_context.Error (e.ToString ());
+ return null;
+ }
+}
+
+/* end end end */
+#endif
+}
Added: trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpTokenizer.cs
===================================================================
--- trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpTokenizer.cs 2005-02-28 23:54:16 UTC (rev 2281)
+++ trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/CSharpTokenizer.cs 2005-03-01 23:58:20 UTC (rev 2282)
@@ -0,0 +1,570 @@
+#if NET_2_0
+using System;
+using System.Text;
+using System.IO;
+using System.Reflection;
+using System.Collections;
+using System.Globalization;
+using Mono.Debugger;
+
+namespace Debugger.Frontend
+{
+ public class SyntaxError : Exception
+ {
+ public SyntaxError (string message)
+ : base ("syntax error: " + message)
+ { }
+ }
+
+ public class Tokenizer : yyParser.yyInput
+ {
+ //
+ // Class variables
+ //
+ static Hashtable keywords;
+ static Hashtable short_keywords;
+ static System.Text.StringBuilder id_builder;
+ static System.Text.StringBuilder string_builder;
+ static System.Text.StringBuilder number_builder;
+
+ //
+ // Values for the associated token returned
+ //
+ int putback_char;
+ Object val;
+
+ //
+ // Class initializer
+ //
+ static Tokenizer ()
+ {
+ InitTokens ();
+ id_builder = new System.Text.StringBuilder ();
+ string_builder = new System.Text.StringBuilder ();
+ number_builder = new System.Text.StringBuilder ();
+ }
+
+ static void InitTokens ()
+ {
+ keywords = new Hashtable ();
+ short_keywords = new Hashtable ();
+
+ keywords.Add ("new", Token.NEW);
+ keywords.Add ("this", Token.THIS);
+ keywords.Add ("base", Token.BASE);
+ keywords.Add ("catch", Token.CATCH);
+ }
+
+ EvaluationContext context;
+ TextReader reader;
+ string ref_name;
+ int current_token;
+ int col = 1;
+
+ //
+ // Whether tokens have been seen on this line
+ //
+ bool tokens_seen = false;
+
+ //
+ // Details about the error encoutered by the tokenizer
+ //
+ string error_details;
+
+ public string error {
+ get {
+ return error_details;
+ }
+ }
+
+ public Tokenizer (EvaluationContext context, TextReader reader, string name)
+ {
+ this.context = context;
+ this.reader = reader;
+ this.ref_name = name;
+ }
+
+ public void restart ()
+ {
+ tokens_seen = false;
+ col = 1;
+ }
+
+ //
+ // Accepts exactly count (4 or 8) hex, no more no less
+ //
+ int getHex (int count, out bool error)
+ {
+ int i;
+ int total = 0;
+ int c;
+ int top = count != -1 ? count : 4;
+
+ getChar ();
+ error = false;
+ for (i = 0; i < top; i++){
+ c = getChar ();
+
+ if (c >= '0' && c <= '9')
+ c = (int) c - (int) '0';
+ else if (c >= 'A' && c <= 'F')
+ c = (int) c - (int) 'A' + 10;
+ else if (c >= 'a' && c <= 'f')
+ c = (int) c - (int) 'a' + 10;
+ else {
+ error = true;
+ return 0;
+ }
+
+ total = (total * 16) + c;
+ if (count == -1){
+ int p = peekChar ();
+ if (p == -1)
+ break;
+ if (!is_hex ((char)p))
+ break;
+ }
+ }
+ return total;
+ }
+
+ int escape (int c)
+ {
+ bool error;
+ int d;
+ int v;
+
+ d = peekChar ();
+ if (c != '\\')
+ return c;
+
+ switch (d){
+ case 'a':
+ v = '\a'; break;
+ case 'b':
+ v = '\b'; break;
+ case 'n':
+ v = '\n'; break;
+ case 't':
+ v = '\t'; break;
+ case 'v':
+ v = '\v'; break;
+ case 'r':
+ v = '\r'; break;
+ case '\\':
+ v = '\\'; break;
+ case 'f':
+ v = '\f'; break;
+ case '0':
+ v = 0; break;
+ case '"':
+ v = '"'; break;
+ case '\'':
+ v = '\''; break;
+ case 'x':
+ v = getHex (-1, out error);
+ if (error)
+ goto default;
+ return v;
+ case 'u':
+ v = getHex (4, out error);
+ if (error)
+ goto default;
+ return v;
+ case 'U':
+ v = getHex (8, out error);
+ if (error)
+ goto default;
+ return v;
+ default:
+// context.Error ("Unrecognized escape sequence in " + (char)d);
+ return d;
+ }
+ getChar ();
+ return v;
+ }
+
+ int getChar ()
+ {
+ if (putback_char != -1){
+ int x = putback_char;
+ putback_char = -1;
+
+ return x;
+ }
+ return reader.Read ();
+ }
+
+ int peekChar ()
+ {
+ if (putback_char != -1)
+ return putback_char;
+ return reader.Peek ();
+ }
+
+ void putback (int c)
+ {
+ if (putback_char != -1)
+ throw new Exception ("This should not happen putback on putback");
+ putback_char = c;
+ }
+
+ public bool advance ()
+ {
+ return peekChar () >= 0;
+ }
+
+ bool is_identifier_start_character (char c)
+ {
+ return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_' || Char.IsLetter (c);
+ }
+
+ bool is_identifier_part_character (char c)
+ {
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= '0' && c <= '9') || Char.IsLetter (c);
+ }
+
+ int GetKeyword (string name, bool tokens_seen)
+ {
+ object o = keywords [name];
+
+ if (o != null)
+ return (int) o;
+
+ if (tokens_seen)
+ return -1;
+
+ o = short_keywords [name];
+ if (o != null)
+ return (int) o;
+
+ return -1;
+ }
+
+ //
+ // Invoked if we know we have .digits or digits
+ //
+ int is_number (int c)
+ {
+ number_builder.Length = 0;
+
+ if (c >= '0' && c <= '9'){
+ if (c == '0' && peekChar () == 'x' || peekChar () == 'X'){
+ getChar ();
+ hex_digits (-1);
+
+ string s = number_builder.ToString ();
+
+ val = (long) System.UInt64.Parse (s, NumberStyles.HexNumber);
+ return Token.NUMBER;
+ }
+ decimal_digits (c);
+
+ val = (int) System.UInt32.Parse (number_builder.ToString ());
+ return Token.INTEGER;
+ }
+
+ throw new Exception ("Is Number should never reach this point");
+ }
+
+ bool decimal_digits (int c)
+ {
+ int d;
+ bool seen_digits = false;
+
+ if (c != -1)
+ number_builder.Append ((char) c);
+
+ while ((d = peekChar ()) != -1){
+ if (d >= '0' && d <= '9'){
+ number_builder.Append ((char) d);
+ getChar ();
+ seen_digits = true;
+ } else
+ break;
+ }
+
+ return seen_digits;
+ }
+
+ bool is_hex (int e)
+ {
+ return (e >= '0' && e <= '9') || (e >= 'A' && e <= 'F') || (e >= 'a' && e <= 'f');
+ }
+
+ void hex_digits (int c)
+ {
+ int d;
+
+ if (c != -1)
+ number_builder.Append ((char) c);
+ while ((d = peekChar ()) != -1){
+ if (is_hex (d)){
+ number_builder.Append ((char) d);
+ getChar ();
+ } else
+ break;
+ }
+ }
+
+ private int consume_identifier (int c, bool quoted)
+ {
+ bool old_tokens_seen = tokens_seen;
+ tokens_seen = true;
+
+ id_builder.Length = 0;
+
+ id_builder.Append ((char) c);
+
+ while ((c = peekChar ()) != -1) {
+ if (is_identifier_part_character ((char) c)){
+ id_builder.Append ((char)getChar ());
+ col++;
+ } else
+ break;
+ }
+
+ string ids = id_builder.ToString ();
+ int keyword = GetKeyword (ids, old_tokens_seen);
+
+ if (keyword == -1 || quoted){
+ val = ids;
+ if (ids.Length > 512){
+// context.Error ("Identifier too long (limit is 512 chars)");
+ }
+ return Token.IDENTIFIER;
+ }
+
+ return keyword;
+ }
+
+ private int consume_string (bool quoted)
+ {
+ int c;
+ string_builder.Length = 0;
+
+ while ((c = getChar ()) != -1){
+ if (c == '"'){
+ if (quoted && peekChar () == '"'){
+ string_builder.Append ((char) c);
+ getChar ();
+ continue;
+ } else {
+ val = string_builder.ToString ();
+ return Token.STRING;
+ }
+ }
+
+ if (c == '\n'){
+// if (!quoted)
+// context.Error ("Newline in constant");
+ col = 0;
+ } else
+ col++;
+
+ if (!quoted){
+ c = escape (c);
+ if (c == -1)
+ return Token.ERROR;
+ }
+ string_builder.Append ((char) c);
+ }
+
+// context.Error ("Unterminated string literal");
+ return Token.EOF;
+ }
+
+ private int consume_quoted_identifier ()
+ {
+ int c;
+
+ id_builder.Length = 0;
+
+ while ((c = getChar ()) != -1){
+ if (c == '\''){
+ val = id_builder.ToString ();
+ return Token.IDENTIFIER;
+ }
+
+ if (c == '\n')
+ col = 0;
+ else
+ col++;
+
+ id_builder.Append ((char) c);
+ }
+
+// context.Error ("Unterminated quoted identifier");
+ return Token.EOF;
+ }
+
+ private string consume_help ()
+ {
+ int c;
+ StringBuilder sb = new StringBuilder ();
+
+ while ((c = getChar ()) != -1){
+ if (c == '\n') {
+ col = 0;
+ return sb.ToString ();
+ }
+
+ col++;
+ sb.Append ((char) c);
+ }
+
+ return sb.ToString ();
+ }
+
+ public int xtoken ()
+ {
+ int c;
+
+ val = null;
+ // optimization: eliminate col and implement #directive semantic correctly.
+ for (;(c = getChar ()) != -1; col++) {
+ if (is_identifier_start_character ((char)c))
+ return consume_identifier (c, false);
+
+ if (c == 0)
+ continue;
+ else if (c == '#')
+ return Token.HASH;
+ else if (c == '@')
+ return Token.AT;
+ else if (c == '%')
+ return Token.PERCENT;
+ else if (c == '$')
+ return Token.DOLLAR;
+ else if (c == '.')
+ if ((c = peekChar ()) == '.') {
+ getChar ();
+ return Token.DOTDOT;
+ }
+ else {
+ return Token.DOT;
+ }
+ else if (c == '!')
+ return Token.BANG;
+ else if (c == '=')
+ return Token.ASSIGN;
+ else if (c == '*')
+ return Token.STAR;
+ else if (c == '+')
+ return Token.PLUS;
+ else if (c == '-') // FIXME: negative numbers...
+ return Token.MINUS;
+ else if (c == '/')
+ return Token.DIV;
+ else if (c == '(')
+ return Token.OPEN_PARENS;
+ else if (c == ')')
+ return Token.CLOSE_PARENS;
+ else if (c == '[')
+ return Token.OPEN_BRACKET;
+ else if (c == ']')
+ return Token.CLOSE_BRACKET;
+ else if (c == ',')
+ return Token.COMMA;
+ else if (c == '<')
+ return Token.OP_LT;
+ else if (c == '>')
+ return Token.OP_GT;
+ else if (c == ':')
+ return Token.COLON;
+ else if (c == '&')
+ return Token.AMPERSAND;
+
+ if (c >= '0' && c <= '9') {
+ tokens_seen = true;
+ return is_number (c);
+ }
+
+ if (c == '"')
+ return consume_string (false);
+
+ if (c == ' ' || c == '\t' || c == '\f' || c == '\v' || c == '\r' || c == '\n'){
+ if (current_token == Token.HASH) {
+ error_details = "No whitespace allowed after `#'";
+ return Token.ERROR;
+ } else if (current_token == Token.AT) {
+ error_details = "No whitespace allowed after `@'";
+ return Token.ERROR;
+ }
+
+ if (c == '\t')
+ col = (((col + 8) / 8) * 8) - 1;
+ continue;
+ }
+
+ if (c == '\'')
+ return consume_quoted_identifier ();
+
+ error_details = "Unknown character `" + (char) c + "'";
+ return Token.ERROR;
+ }
+
+ return Token.EOF;
+ }
+
+ public int token ()
+ {
+ current_token = xtoken ();
+ return current_token;
+ }
+
+ public Object value ()
+ {
+ return val;
+ }
+
+ static Hashtable tokenValues;
+
+ private static Hashtable TokenValueName
+ {
+ get {
+ if (tokenValues == null)
+ tokenValues = GetTokenValueNameHash ();
+
+ return tokenValues;
+ }
+ }
+
+ private static Hashtable GetTokenValueNameHash ()
+ {
+ Type t = typeof (Token);
+ FieldInfo [] fields = t.GetFields ();
+ Hashtable hash = new Hashtable ();
+ foreach (FieldInfo field in fields) {
+ if (field.IsLiteral && field.IsStatic && field.FieldType == typeof (int))
+ hash.Add (field.GetValue (null), field.Name);
+ }
+ return hash;
+ }
+
+ //
+ // Returns a verbose representation of the current location
+ //
+ public string location {
+ get {
+ string det;
+
+ if (current_token == Token.ERROR)
+ det = "detail: " + error_details;
+ else
+ det = "";
+
+ // return "Line: "+line+" Col: "+col + "\n" +
+ // "VirtLine: "+ref_line +
+ // " Token: "+current_token + " " + det;
+ string current_token_name = TokenValueName [current_token] as string;
+ if (current_token_name == null)
+ current_token_name = current_token.ToString ();
+
+ return String.Format ("{0}, Token: {1} {2}", ref_name,
+ current_token_name, det);
+ }
+ }
+ }
+}
+#endif
Modified: trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/ChangeLog
===================================================================
--- trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/ChangeLog 2005-02-28 23:54:16 UTC (rev 2281)
+++ trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/ChangeLog 2005-03-01 23:58:20 UTC (rev 2282)
@@ -1,3 +1,31 @@
+2005-03-01 Chris Toshok <toshok at ximian.com>
+
+ * Gui/DebuggerVariablePad.cs (DebuggerVariablePad.add_member):
+ strip out the part of add_struct that adds individual fields and
+ implement all the DebuggerBrowsableAttribute handling.
+ (DebuggerVariablePad.add_struct): display both fields and
+ properties.
+ (DebuggerVariablePad.GetDebuggerBrowsableAttribute): returns the
+ first DebuggerBrowsable attribute for a given ITargetMemberInfo,
+ if there are any.
+ (DebuggerVariablePad.GetDebuggerDisplayAttribute): returns the
+ first DebuggerDisplay attribute for a given ITargetObject, if
+ there are any.
+ (DebuggerVariablePad.EvaluateDebuggerDisplay): given the
+ DebuggerDisplay attribute's value, evaluate any nested
+ {expressions} and convert them all to strings.
+ (DebuggerVariablePad.add_object): if it's a struct or class, add
+ the DebuggerDisplay if there is one.
+
+ * DebuggingService.cs (MainThread): add a getter for this, so we
+ can grab a thread with which to evaluate expressions in
+ DebuggerDisplayAttributes.
+
+ * Makefile.am (FILES): add stripped down files from the debugger
+ source - EvaluationContext.cs (formerly ScriptingContext),
+ Expression.cs, MyTextReader.cs, CSharpTokenizer.cs, and
+ CSharpExpressionParser.cs.
+
2005-02-25 Chris Toshok <toshok at ximian.com>
* Gui/DebuggerVariablePad.cs (DebuggerVariablePad.add_data): fix
Modified: trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/DebuggingService.cs
===================================================================
--- trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/DebuggingService.cs 2005-02-28 23:54:16 UTC (rev 2281)
+++ trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/DebuggingService.cs 2005-03-01 23:58:20 UTC (rev 2282)
@@ -323,12 +323,20 @@
}
}
+#if NET_2_0
+ public Process MainThread {
+ get {
+ return proc;
+ }
+ }
+#endif
+
public Process[] Threads {
- get {
+ get {
Process[] retval = new Process [procs.Count];
procs.Values.CopyTo (retval, 0);
return retval;
- }
+ }
}
public object CurrentFrame {
Added: trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/EvaluationContext.cs
===================================================================
--- trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/EvaluationContext.cs 2005-02-28 23:54:16 UTC (rev 2281)
+++ trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/EvaluationContext.cs 2005-03-01 23:58:20 UTC (rev 2282)
@@ -0,0 +1,251 @@
+#if NET_2_0
+using System;
+using System.Collections;
+using Mono.Debugger;
+using Mono.Debugger.Languages;
+
+namespace Debugger.Frontend {
+
+ public class FrameHandle
+ {
+ StackFrame frame;
+
+ public FrameHandle (StackFrame frame)
+ {
+ this.frame = frame;
+ }
+
+ public StackFrame Frame {
+ get { return frame; }
+ }
+
+ public ILanguage Language {
+ get {
+ if (frame.Language == null)
+ throw new EvaluationException (
+ "Stack frame has no source language.");
+
+ return frame.Language;
+ }
+ }
+ }
+
+ public class BacktraceHandle
+ {
+ FrameHandle[] frames;
+
+ public BacktraceHandle (ProcessHandle process, Backtrace backtrace)
+ {
+ StackFrame[] bt_frames = backtrace.Frames;
+ if (bt_frames != null) {
+ frames = new FrameHandle [bt_frames.Length];
+ for (int i = 0; i < frames.Length; i++)
+ frames [i] = new FrameHandle (bt_frames [i]);
+ } else
+ frames = new FrameHandle [0];
+ }
+
+ public int Length {
+ get { return frames.Length; }
+ }
+
+ public FrameHandle this [int number] {
+ get { return frames [number]; }
+ }
+ }
+
+ public class ProcessHandle
+ {
+ ThreadGroup tgroup;
+ Process process;
+ string name;
+ int id;
+
+ public ProcessHandle (Process process)
+ {
+ this.process = process;
+ this.name = process.Name;
+ this.id = process.ID;
+ }
+
+
+ public ProcessHandle (Process process, int pid)
+ : this (process)
+ {
+ if (process.HasTarget) {
+ if (!process.IsDaemon) {
+ StackFrame frame = process.CurrentFrame;
+ current_frame = new FrameHandle (frame);
+ }
+ }
+ }
+
+ public Process Process {
+ get { return process; }
+ }
+
+ public ThreadGroup ThreadGroup {
+ get { return tgroup; }
+ }
+
+ BacktraceHandle current_backtrace = null;
+
+ int current_frame_idx = -1;
+ FrameHandle current_frame = null;
+ AssemblerLine current_insn = null;
+
+ public int CurrentFrameIndex {
+ get {
+ if (current_frame_idx == -1)
+ return 0;
+
+ return current_frame_idx;
+ }
+
+ set {
+ GetBacktrace (-1);
+ if ((value < 0) || (value >= current_backtrace.Length))
+ throw new EvaluationException ("No such frame.");
+
+ current_frame_idx = value;
+ current_frame = current_backtrace [current_frame_idx];
+ }
+ }
+
+
+ public BacktraceHandle GetBacktrace (int max_frames)
+ {
+ if (State == TargetState.NO_TARGET)
+ throw new EvaluationException ("No stack.");
+ else if (!process.IsStopped)
+ throw new EvaluationException ("{0} is not stopped.", Name);
+
+ if ((max_frames == -1) && (current_backtrace != null))
+ return current_backtrace;
+
+ current_backtrace = new BacktraceHandle (this, process.GetBacktrace (max_frames));
+
+ if (current_backtrace == null)
+ throw new EvaluationException ("No stack.");
+
+ return current_backtrace;
+ }
+
+ public FrameHandle CurrentFrame {
+ get {
+ return GetFrame (current_frame_idx);
+ }
+ }
+
+ public FrameHandle GetFrame (int number)
+ {
+ if (State == TargetState.NO_TARGET)
+ throw new EvaluationException ("No stack.");
+ else if (!process.IsStopped)
+ throw new EvaluationException ("{0} is not stopped.", Name);
+
+ if (number == -1) {
+ if (current_frame == null)
+ current_frame = new FrameHandle (process.CurrentFrame);
+
+ return current_frame;
+ }
+
+ GetBacktrace (-1);
+ if (number >= current_backtrace.Length)
+ throw new EvaluationException ("No such frame: {0}", number);
+
+ return current_backtrace [number];
+ }
+
+ public TargetState State {
+ get {
+ if (process == null)
+ return TargetState.NO_TARGET;
+ else
+ return process.State;
+ }
+ }
+
+ public string Name {
+ get {
+ return name;
+ }
+ }
+ }
+
+ public class EvaluationException : Exception
+ {
+ public EvaluationException (string format, params object[] args)
+ : base (String.Format (format, args))
+ { }
+ }
+
+ public class EvaluationContext
+ {
+ ProcessHandle current_process;
+ int current_frame_idx = -1;
+ ITargetObject this_obj;
+
+ static AddressDomain address_domain = new AddressDomain ("Evaluation");
+
+ public EvaluationContext (ITargetObject this_obj)
+ {
+ this.this_obj = this_obj;
+ }
+
+ public ITargetObject This {
+ get {
+ return this_obj;
+ }
+ }
+
+ public ProcessHandle CurrentProcess {
+ get { return current_process; }
+ set { current_process = value; }
+ }
+
+ public FrameHandle CurrentFrame {
+ get {
+ return current_process.GetFrame (current_frame_idx);
+ }
+ }
+
+ public int CurrentFrameIndex {
+ get {
+ return current_frame_idx;
+ }
+
+ set {
+ current_frame_idx = value;
+ }
+ }
+
+ public string[] GetNamespaces (FrameHandle frame)
+ {
+ IMethod method = frame.Frame.Method;
+ if ((method == null) || !method.HasSource)
+ return null;
+
+ MethodSource msource = method.Source;
+ if (msource.IsDynamic)
+ return null;
+
+ return msource.GetNamespaces ();
+ }
+
+ public string[] GetNamespaces ()
+ {
+ return GetNamespaces (CurrentFrame);
+ }
+
+ public AddressDomain AddressDomain {
+ get {
+ return address_domain;
+ }
+ }
+
+ }
+
+}
+#endif
Added: trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Expression.cs
===================================================================
--- trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Expression.cs 2005-02-28 23:54:16 UTC (rev 2281)
+++ trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Expression.cs 2005-03-01 23:58:20 UTC (rev 2282)
@@ -0,0 +1,1604 @@
+#if NET_2_0
+using System;
+using System.Text;
+using System.IO;
+using System.Reflection;
+using System.Collections;
+using System.Globalization;
+using Mono.Debugger;
+using Mono.Debugger.Languages;
+
+namespace Debugger.Frontend
+{
+ public enum LocationType
+ {
+ Method,
+ PropertyGetter,
+ PropertySetter,
+ EventAdd,
+ EventRemove
+ }
+
+ public abstract class Expression
+ {
+ public abstract string Name {
+ get;
+ }
+
+ protected bool resolved;
+
+ protected virtual ITargetType DoEvaluateType (EvaluationContext context)
+ {
+ return EvaluateVariable (context).TypeInfo.Type;
+ }
+
+ public ITargetType EvaluateType (EvaluationContext context)
+ {
+ if (!resolved)
+ throw new InvalidOperationException (
+ String.Format (
+ "Some clown tried to evaluate the " +
+ "unresolved expression `{0}'", Name));
+
+ try {
+ ITargetType type = DoEvaluateType (context);
+ if (type == null)
+ throw new EvaluationException (
+ "Cannot get type of expression `{0}'", Name);
+
+ return type;
+ } catch (LocationInvalidException ex) {
+ throw new EvaluationException (
+ "Location of variable `{0}' is invalid: {1}",
+ Name, ex.Message);
+ }
+ }
+
+ protected virtual object DoEvaluate (EvaluationContext context)
+ {
+ return DoEvaluateVariable (context);
+ }
+
+ public object Evaluate (EvaluationContext context)
+ {
+ if (!resolved)
+ throw new InvalidOperationException (
+ String.Format (
+ "Some clown tried to evaluate the " +
+ "unresolved expression `{0}'", Name));
+
+ object result = DoEvaluate (context);
+ if (result == null)
+ throw new EvaluationException (
+ "Cannot evaluate expression `{0}'", Name);
+
+ return result;
+ }
+
+ protected virtual ITargetObject DoEvaluateVariable (EvaluationContext context)
+ {
+ return null;
+ }
+
+ public ITargetObject EvaluateVariable (EvaluationContext context)
+ {
+ if (!resolved)
+ throw new InvalidOperationException (
+ String.Format (
+ "Some clown tried to evaluate the " +
+ "unresolved expression `{0}' ({1})", Name,
+ GetType ()));
+
+ try {
+ ITargetObject retval = DoEvaluateVariable (context);
+ if (retval == null)
+ throw new EvaluationException (
+ "Expression `{0}' is not a variable", Name);
+
+ return retval;
+ } catch (LocationInvalidException ex) {
+ throw new EvaluationException (
+ "Location of variable `{0}' is invalid: {1}",
+ Name, ex.Message);
+ }
+ }
+
+ protected virtual SourceLocation DoEvaluateLocation (EvaluationContext context,
+ LocationType type, Expression[] types)
+ {
+ return null;
+ }
+
+ public SourceLocation EvaluateLocation (EvaluationContext context, LocationType type,
+ Expression [] types)
+ {
+ if (!resolved)
+ throw new InvalidOperationException (
+ String.Format (
+ "Some clown tried to evaluate the " +
+ "unresolved expression `{0}'", Name));
+
+ try {
+ SourceLocation location = DoEvaluateLocation (context, type, types);
+ if (location == null)
+ throw new EvaluationException (
+ "Expression `{0}' is not a method", Name);
+
+ return location;
+ } catch (LocationInvalidException ex) {
+ throw new EvaluationException (
+ "Location of variable `{0}' is invalid: {1}",
+ Name, ex.Message);
+ }
+ }
+
+ protected virtual bool DoAssign (EvaluationContext context, ITargetObject obj)
+ {
+ return false;
+ }
+
+ public void Assign (EvaluationContext context, ITargetObject obj)
+ {
+ if (!resolved)
+ throw new InvalidOperationException (
+ String.Format (
+ "Some clown tried to evaluate the " +
+ "unresolved expression `{0}'", Name));
+
+ bool ok = DoAssign (context, obj);
+ if (!ok)
+ throw new EvaluationException (
+ "Expression `{0}' is not an lvalue", Name);
+ }
+
+ protected virtual Expression DoResolveType (EvaluationContext context)
+ {
+ return null;
+ }
+
+ public Expression ResolveType (EvaluationContext context)
+ {
+ Expression expr = DoResolveType (context);
+ if (expr == null)
+ throw new EvaluationException (
+ "Expression `{0}' is not a type.", Name);
+
+ return expr;
+ }
+
+ public Expression TryResolveType (EvaluationContext context)
+ {
+ try {
+ return DoResolveType (context);
+ } catch (EvaluationException) {
+ return null;
+ } catch (Mono.Debugger.TargetException) {
+ return null;
+ }
+ }
+
+ protected abstract Expression DoResolve (EvaluationContext context);
+
+ public Expression Resolve (EvaluationContext context)
+ {
+ Expression expr = DoResolve (context);
+ if (expr == null)
+ throw new EvaluationException (
+ "Expression `{0}' is not a variable or value.", Name);
+
+ return expr;
+ }
+
+ public Expression TryResolve (EvaluationContext context)
+ {
+ try {
+ return DoResolve (context);
+ } catch (EvaluationException) {
+ return null;
+ } catch (Mono.Debugger.TargetException) {
+ return null;
+ }
+ }
+
+ public override string ToString ()
+ {
+ return String.Format ("{0} ({1})", GetType (), Name);
+ }
+ }
+
+ public class NumberExpression : PointerExpression
+ {
+ object val;
+
+ public NumberExpression (int val)
+ {
+ this.val = val;
+ }
+
+ public NumberExpression (long val)
+ {
+ this.val = val;
+ }
+
+ public long Value {
+ get {
+ if (val is int)
+ return (long) (int) val;
+ else
+ return (long) val;
+ }
+ }
+
+ public override string Name {
+ get {
+ if (val is long)
+ return String.Format ("0x{0:x}", (long) val);
+ else
+ return val.ToString ();
+ }
+ }
+
+ protected override Expression DoResolve (EvaluationContext context)
+ {
+ resolved = true;
+ return this;
+ }
+
+ protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+ {
+ StackFrame frame = context.CurrentFrame.Frame;
+ if ((frame.Language == null) ||
+ !frame.Language.CanCreateInstance (val.GetType ()))
+ return null;
+
+ return frame.Language.CreateInstance (frame, val);
+ }
+
+ public override TargetLocation EvaluateAddress (EvaluationContext context)
+ {
+ TargetAddress addr = new TargetAddress (context.AddressDomain, Value);
+ return new AbsoluteTargetLocation (context.CurrentFrame.Frame, addr);
+ }
+
+ protected override object DoEvaluate (EvaluationContext context)
+ {
+ return val;
+ }
+ }
+
+ public class StringExpression : Expression
+ {
+ string val;
+
+ public StringExpression (string val)
+ {
+ this.val = val;
+ }
+
+ public override string Name {
+ get { return val; }
+ }
+
+ protected override Expression DoResolve (EvaluationContext context)
+ {
+ resolved = true;
+ return this;
+ }
+
+ protected override object DoEvaluate (EvaluationContext context)
+ {
+ return val;
+ }
+
+ protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+ {
+ StackFrame frame = context.CurrentFrame.Frame;
+ if ((frame.Language == null) ||
+ !frame.Language.CanCreateInstance (typeof (string)))
+ return null;
+
+ return frame.Language.CreateInstance (frame, val);
+ }
+ }
+
+ public class ThisExpression : Expression
+ {
+ public override string Name {
+ get { return "this"; }
+ }
+
+ protected FrameHandle frame;
+ protected IVariable var;
+
+ protected override Expression DoResolve (EvaluationContext context)
+ {
+ frame = context.CurrentFrame;
+ IMethod method = frame.Frame.Method;
+ if (method == null)
+ throw new EvaluationException (
+ "Keyword `this' not allowed: no current method.");
+
+ if (!method.HasThis)
+ throw new EvaluationException (
+ "Keyword `this' not allowed: current method is " +
+ "either static or unmanaged.");
+
+ var = method.This;
+ resolved = true;
+ return this;
+ }
+
+ protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+ {
+ return context.This;
+ }
+ }
+
+ public class BaseExpression : ThisExpression
+ {
+ public override string Name {
+ get { return "base"; }
+ }
+
+ protected override Expression DoResolve (EvaluationContext context)
+ {
+ Expression expr = base.DoResolve (context);
+ if (expr == null)
+ return null;
+
+ if (var.Type.Kind != TargetObjectKind.Class)
+ throw new EvaluationException (
+ "`base' is only allowed in a class.");
+ if (!((ITargetClassType) var.Type).HasParent)
+ throw new EvaluationException (
+ "Current class has no base class.");
+
+ return expr;
+ }
+
+ protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+ {
+ return ((ITargetClassObject) base.DoEvaluateVariable (context)).Parent;
+ }
+ }
+
+ public class TypeExpression : Expression
+ {
+ ITargetType type;
+
+ public TypeExpression (ITargetType type)
+ {
+ this.type = type;
+ resolved = true;
+ }
+
+ public override string Name {
+ get { return type.Name; }
+ }
+
+ protected override Expression DoResolveType (EvaluationContext context)
+ {
+ return this;
+ }
+
+ protected override Expression DoResolve (EvaluationContext context)
+ {
+ return this;
+ }
+
+ protected override ITargetType DoEvaluateType (EvaluationContext context)
+ {
+ return type;
+ }
+
+ protected override object DoEvaluate (EvaluationContext context)
+ {
+ return type;
+ }
+ }
+
+ public class SourceExpression : Expression
+ {
+ SourceLocation location;
+
+ public SourceExpression (SourceLocation location)
+ {
+ this.location = location;
+ resolved = true;
+ }
+
+ public override string Name {
+ get { return location.Name; }
+ }
+
+ protected override Expression DoResolve (EvaluationContext context)
+ {
+ resolved = true;
+ return this;
+ }
+
+ protected override SourceLocation DoEvaluateLocation (EvaluationContext context,
+ LocationType type, Expression[] types)
+ {
+ if (types != null)
+ return null;
+
+ return location;
+ }
+ }
+
+ public class SimpleNameExpression : Expression
+ {
+ string name;
+
+ public SimpleNameExpression (string name)
+ {
+ this.name = name;
+ }
+
+ public override string Name {
+ get { return name; }
+ }
+
+ public static string MakeFQN (string nsn, string name)
+ {
+ if (nsn == "")
+ return name;
+ return String.Concat (nsn, ".", name);
+ }
+
+ Expression LookupMember (EvaluationContext context, FrameHandle frame,
+ string full_name)
+ {
+ return StructAccessExpression.FindMember (
+ context.This.TypeInfo.Type as ITargetStructType, frame.Frame,
+ (ITargetStructObject) context.This, false, full_name);
+ }
+
+ Expression Lookup (EvaluationContext context, FrameHandle frame)
+ {
+ string[] namespaces = context.GetNamespaces (frame);
+ if (namespaces == null)
+ return null;
+
+ foreach (string ns in namespaces) {
+ string full_name = MakeFQN (ns, name);
+ Expression expr = LookupMember (context, frame, full_name);
+ if (expr != null)
+ return expr;
+ }
+
+ return null;
+ }
+
+ protected override Expression DoResolve (EvaluationContext context)
+ {
+ FrameHandle frame = context.CurrentFrame;
+
+ Expression expr = LookupMember (context, frame, name);
+ if (expr != null)
+ return expr;
+
+ expr = Lookup (context, frame);
+ if (expr != null)
+ return expr;
+
+// SourceLocation location = context.Interpreter.FindMethod (name);
+// if (location != null)
+// return new SourceExpression (location);
+
+ expr = DoResolveType (context);
+ if (expr != null)
+ return expr;
+
+ throw new EvaluationException ("No such type of method: `{0}'", Name);
+ }
+
+ protected override Expression DoResolveType (EvaluationContext context)
+ {
+ FrameHandle frame = context.CurrentFrame;
+ ITargetType type = frame.Language.LookupType (frame.Frame, name);
+ if (type != null)
+ return new TypeExpression (type);
+
+ string[] namespaces = context.GetNamespaces (frame);
+ if (namespaces == null)
+ return null;
+
+ foreach (string ns in namespaces) {
+ string full_name = MakeFQN (ns, name);
+ type = frame.Language.LookupType (frame.Frame, full_name);
+ if (type != null)
+ return new TypeExpression (type);
+ }
+
+ return null;
+ }
+ }
+
+ public class MemberAccessExpression : Expression
+ {
+ Expression left;
+ string name;
+
+ public MemberAccessExpression (Expression left, string name)
+ {
+ this.left = left;
+ this.name = name;
+ }
+
+ public override string Name {
+ get { return left.Name + "." + name; }
+ }
+
+ public Expression ResolveMemberAccess (EvaluationContext context, bool allow_instance)
+ {
+ StackFrame frame = context.CurrentFrame.Frame;
+
+ Expression expr;
+ Expression ltype = left.TryResolveType (context);
+ if (ltype != null) {
+ ITargetStructType stype = ltype.EvaluateType (context)
+ as ITargetStructType;
+ if (stype == null)
+ throw new EvaluationException (
+ "`{0}' is not a struct or class", ltype.Name);
+
+ expr = StructAccessExpression.FindMember (
+ stype, frame, null, allow_instance, name);
+ if (expr == null)
+ throw new EvaluationException (
+ "Type `{0}' has no member `{1}'",
+ stype.Name, name);
+
+ return expr;
+ }
+
+ Expression lexpr = left.TryResolve (context);
+ if (lexpr == null)
+ throw new EvaluationException (
+ "No such variable or type: `{0}'", left.Name);
+
+ ITargetStructObject sobj = lexpr.EvaluateVariable (context)
+ as ITargetStructObject;
+ if (sobj == null)
+ throw new EvaluationException (
+ "`{0}' is not a struct or class", left.Name);
+
+ expr = StructAccessExpression.FindMember (
+ sobj.Type, frame, sobj, true, name);
+ if (expr == null)
+ throw new EvaluationException (
+ "Type `{0}' has no member `{1}'",
+ sobj.Type.Name, name);
+
+ return expr;
+ }
+
+ protected override Expression DoResolve (EvaluationContext context)
+ {
+ return ResolveMemberAccess (context, false);
+ }
+
+ protected override Expression DoResolveType (EvaluationContext context)
+ {
+ StackFrame frame = context.CurrentFrame.Frame;
+
+ ITargetType the_type;
+
+ Expression ltype = left.TryResolveType (context);
+ if (ltype == null)
+ the_type = frame.Language.LookupType (frame, Name);
+ else {
+ string nested = ltype.Name + "+" + name;
+ the_type = frame.Language.LookupType (frame, nested);
+ }
+
+ if (the_type == null)
+ return null;
+
+ return new TypeExpression (the_type);
+ }
+ }
+
+ public class MethodGroupExpression : Expression
+ {
+ ITargetStructType stype;
+ ITargetStructObject instance;
+ ILanguage language;
+ string name;
+ ArrayList methods;
+
+ public MethodGroupExpression (ITargetStructType stype, string name,
+ ITargetStructObject instance,
+ ILanguage language, ArrayList methods)
+ {
+ this.stype = stype;
+ this.instance = instance;
+ this.language = language;
+ this.name = name;
+ this.methods = methods;
+ resolved = true;
+ }
+
+ public override string Name {
+ get { return stype.Name + "." + name; }
+ }
+
+ public bool IsStatic {
+ get { return instance == null; }
+ }
+
+ protected override Expression DoResolve (EvaluationContext context)
+ {
+ return this;
+ }
+
+ protected override SourceLocation DoEvaluateLocation (EvaluationContext context,
+ LocationType type, Expression[] types)
+ {
+ try {
+ ITargetMethodInfo method = OverloadResolve (context, types);
+ return new SourceLocation (method.Type.Source);
+ } catch {
+// ArrayList list = new ArrayList ();
+// foreach (ITargetMethodInfo method in methods) {
+// if (method.Type.Source == null)
+// continue;
+// list.Add (method.Type.Source);
+// }
+// SourceMethod[] sources = new SourceMethod [list.Count];
+// list.CopyTo (sources, 0);
+// throw new MultipleLocationsMatchException (sources);
+ return null;
+ }
+ }
+
+ public ITargetFunctionObject EvaluateMethod (EvaluationContext context,
+ StackFrame frame,
+ Expression[] arguments)
+ {
+ ITargetMethodInfo method = OverloadResolve (context, arguments);
+
+ if (method.IsStatic)
+ return stype.GetStaticMethod (frame, method.Index);
+ else if (!IsStatic)
+ return instance.GetMethod (method.Index);
+ else
+ throw new EvaluationException (
+ "Instance method {0} cannot be used in " +
+ "static context.", Name);
+ }
+
+ protected ITargetMethodInfo OverloadResolve (EvaluationContext context,
+ Expression[] types)
+ {
+ ArrayList candidates = new ArrayList ();
+
+ foreach (ITargetMethodInfo method in methods) {
+ if ((types != null) &&
+ (method.Type.ParameterTypes.Length != types.Length))
+ continue;
+
+ candidates.Add (method);
+ }
+
+ if (candidates.Count == 1)
+ return (ITargetMethodInfo) candidates [0];
+
+ if (candidates.Count == 0)
+ throw new EvaluationException (
+ "No overload of method `{0}' has {1} arguments.",
+ Name, types.Length);
+
+ if (types == null)
+ throw new EvaluationException (
+ "Ambiguous method `{0}'; need to use " +
+ "full name", Name);
+
+ ITargetMethodInfo match = OverloadResolve (
+ context, language, stype, types, candidates);
+
+ if (match == null)
+ throw new EvaluationException (
+ "Ambiguous method `{0}'; need to use " +
+ "full name", Name);
+
+ return match;
+ }
+
+ public static ITargetMethodInfo OverloadResolve (EvaluationContext context,
+ ILanguage language,
+ ITargetStructType stype,
+ Expression[] types,
+ ArrayList candidates)
+ {
+ // We do a very simple overload resolution here
+ ITargetType[] argtypes = new ITargetType [types.Length];
+ for (int i = 0; i < types.Length; i++)
+ argtypes [i] = types [i].EvaluateType (context);
+
+ // Ok, no we need to find an exact match.
+ ITargetMethodInfo match = null;
+ foreach (ITargetMethodInfo method in candidates) {
+ bool ok = true;
+ for (int i = 0; i < types.Length; i++) {
+ if (method.Type.ParameterTypes [i].TypeHandle != argtypes [i].TypeHandle) {
+ ok = false;
+ break;
+ }
+ }
+
+ if (!ok)
+ continue;
+
+ // We need to find exactly one match
+ if (match != null)
+ return null;
+
+ match = method;
+ }
+
+ return match;
+ }
+ }
+
+ public class TypeOfExpression : Expression
+ {
+ Expression expr;
+
+ public TypeOfExpression (Expression expr)
+ {
+ this.expr = expr;
+ }
+
+ public override string Name {
+ get { return String.Format ("typeof ({0})", expr.Name); }
+ }
+
+ protected override Expression DoResolveType (EvaluationContext context)
+ {
+ return expr.ResolveType (context);
+ }
+
+ protected override Expression DoResolve (EvaluationContext context)
+ {
+ return expr.Resolve (context);
+ }
+ }
+
+ public abstract class PointerExpression : Expression
+ {
+ public abstract TargetLocation EvaluateAddress (EvaluationContext context);
+ }
+
+ public class StructAccessExpression : Expression
+ {
+ string name;
+
+ public readonly string Identifier;
+ public readonly bool IsStatic;
+
+ ITargetStructType Type;
+ ITargetStructObject Instance;
+ StackFrame Frame;
+
+ protected StructAccessExpression (StackFrame frame, ITargetStructType type,
+ string identifier)
+ {
+ this.Frame = frame;
+ this.Type = type;
+ this.Identifier = identifier;
+ this.IsStatic = true;
+ resolved = true;
+ }
+
+ protected StructAccessExpression (StackFrame frame,
+ ITargetStructObject instance,
+ string identifier)
+ {
+ this.Frame = frame;
+ this.Type = instance.Type;
+ this.Instance = instance;
+ this.Identifier = identifier;
+ this.IsStatic = false;
+ resolved = true;
+ }
+
+ public override string Name {
+ get {
+ return Identifier;
+ }
+ }
+
+ protected override Expression DoResolve (EvaluationContext context)
+ {
+ return this;
+ }
+
+ protected ITargetObject GetField (ITargetStructObject sobj, ITargetFieldInfo field)
+ {
+ try {
+ return sobj.GetField (field.Index);
+ } catch (Mono.Debugger.TargetInvocationException ex) {
+ throw new EvaluationException ("Can't get field {0}: {1}", Name, ex.Message);
+ }
+ }
+
+ protected ITargetObject GetStaticField (ITargetStructType stype, StackFrame frame, ITargetFieldInfo field)
+ {
+ try {
+ return stype.GetStaticField (frame, field.Index);
+ } catch (Mono.Debugger.TargetInvocationException ex) {
+ throw new EvaluationException ("Can't get field {0}: {1}", Name, ex.Message);
+ }
+ }
+
+ protected ITargetObject GetProperty (ITargetStructObject sobj, ITargetPropertyInfo property)
+ {
+ try {
+ return sobj.GetProperty (property.Index);
+ } catch (Mono.Debugger.TargetInvocationException ex) {
+ throw new EvaluationException ("Can't get property {0}: {1}", Name, ex.Message);
+ }
+ }
+
+ protected ITargetObject GetStaticProperty (ITargetStructType stype, StackFrame frame, ITargetPropertyInfo property)
+ {
+ try {
+ return stype.GetStaticProperty (frame, property.Index);
+ } catch (Mono.Debugger.TargetInvocationException ex) {
+ throw new EvaluationException ("Can't get property {0}: {1}", Name, ex.Message);
+ }
+ }
+
+ protected ITargetObject GetEvent (ITargetStructObject sobj, ITargetEventInfo ev)
+ {
+ try {
+ return sobj.GetEvent (ev.Index);
+ } catch (Mono.Debugger.TargetInvocationException ex) {
+ throw new EvaluationException ("Can't get event {0}: {1}", Name, ex.Message);
+ }
+ }
+
+ protected ITargetObject GetStaticEvent (ITargetStructType stype, StackFrame frame, ITargetEventInfo ev)
+ {
+ try {
+ return stype.GetStaticEvent (frame, ev.Index);
+ } catch (Mono.Debugger.TargetInvocationException ex) {
+ throw new EvaluationException ("Can't get event {0}: {1}", Name, ex.Message);
+ }
+ }
+
+ protected ITargetObject GetMember (ITargetStructObject sobj, ITargetMemberInfo member)
+ {
+ if (member is ITargetPropertyInfo)
+ return GetProperty (sobj, (ITargetPropertyInfo) member);
+ else if (member is ITargetEventInfo)
+ return GetEvent (sobj, (ITargetEventInfo) member);
+ else
+ return GetField (sobj, (ITargetFieldInfo) member);
+ }
+
+ protected ITargetObject GetStaticMember (ITargetStructType stype, StackFrame frame, ITargetMemberInfo member)
+ {
+ if (member is ITargetPropertyInfo)
+ return GetStaticProperty (stype, frame, (ITargetPropertyInfo) member);
+ else if (member is ITargetEventInfo)
+ return GetStaticEvent (stype, frame, (ITargetEventInfo) member);
+ else
+ return GetStaticField (stype, frame, (ITargetFieldInfo) member);
+ }
+
+ public static ITargetMemberInfo FindMember (ITargetStructType stype, bool is_static, string name)
+ {
+ if (!is_static) {
+ foreach (ITargetFieldInfo field in stype.Fields)
+ if (field.Name == name)
+ return field;
+
+ foreach (ITargetPropertyInfo property in stype.Properties)
+ if (property.Name == name)
+ return property;
+
+ foreach (ITargetEventInfo ev in stype.Events)
+ if (ev.Name == name)
+ return ev;
+ }
+
+ foreach (ITargetFieldInfo field in stype.StaticFields)
+ if (field.Name == name)
+ return field;
+
+ foreach (ITargetPropertyInfo property in stype.StaticProperties)
+ if (property.Name == name)
+ return property;
+
+ foreach (ITargetEventInfo ev in stype.StaticEvents)
+ if (ev.Name == name)
+ return ev;
+
+ return null;
+ }
+
+ public static Expression FindMember (ITargetStructType stype, StackFrame frame,
+ ITargetStructObject instance, bool allow_instance,
+ string name)
+ {
+ ITargetMemberInfo member = FindMember (stype, (instance == null) && !allow_instance, name);
+ if (member != null) {
+ if (instance != null)
+ return new StructAccessExpression (frame, instance, name);
+ else
+ return new StructAccessExpression (frame, stype, name);
+ }
+
+ ArrayList methods = new ArrayList ();
+
+ again:
+ if (name == ".ctor") {
+ foreach (ITargetMethodInfo method in stype.Constructors) {
+ methods.Add (method);
+ }
+ }
+ else if (name == ".cctor") {
+ foreach (ITargetMethodInfo method in stype.StaticConstructors) {
+ methods.Add (method);
+ }
+ }
+ else {
+ if ((instance != null) || allow_instance) {
+ foreach (ITargetMethodInfo method in stype.Methods) {
+ if (method.Name != name)
+ continue;
+
+ methods.Add (method);
+ }
+ }
+
+ foreach (ITargetMethodInfo method in stype.StaticMethods) {
+ if (method.Name != name)
+ continue;
+
+ methods.Add (method);
+ }
+ }
+
+
+ if (methods.Count > 0)
+ return new MethodGroupExpression (
+ stype, name, instance, frame.Language, methods);
+
+ ITargetClassType ctype = stype as ITargetClassType;
+ if ((ctype != null) && ctype.HasParent) {
+ stype = ctype.ParentType;
+ goto again;
+ }
+
+ return null;
+ }
+
+ protected ITargetMemberInfo FindMember (EvaluationContext context, bool report_error)
+ {
+ ITargetMemberInfo member = FindMember (Type, IsStatic, Identifier);
+ if ((member != null) || !report_error)
+ return member;
+
+ if (IsStatic)
+ throw new EvaluationException ("Type {0} has no static member {1}.", Type.Name, Identifier);
+ else
+ throw new EvaluationException ("Type {0} has no member {1}.", Type.Name, Identifier);
+ }
+
+ protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+ {
+ ITargetMemberInfo member = FindMember (context, true);
+
+ if (member.IsStatic)
+ return GetStaticMember (Type, Frame, member);
+ else if (!IsStatic)
+ return GetMember (Instance, member);
+ else
+ throw new EvaluationException ("Instance member {0} cannot be used in static context.", Name);
+ }
+
+ protected override SourceLocation DoEvaluateLocation (EvaluationContext context,
+ LocationType type, Expression[] types)
+ {
+ ITargetMemberInfo member = FindMember (context, true);
+ if (member == null)
+ return null;
+
+ ITargetFunctionType func;
+
+ switch (type) {
+ case LocationType.PropertyGetter:
+ case LocationType.PropertySetter:
+ ITargetPropertyInfo property = member as ITargetPropertyInfo;
+ if (property == null)
+ return null;
+
+ if (type == LocationType.PropertyGetter) {
+ if (!property.CanRead)
+ throw new EvaluationException (
+ "Property {0} doesn't have a getter.", Name);
+ func = property.Getter;
+ } else {
+ if (!property.CanWrite)
+ throw new EvaluationException (
+ "Property {0} doesn't have a setter.", Name);
+ func = property.Setter;
+ }
+
+ return new SourceLocation (func.Source);
+ case LocationType.EventAdd:
+ case LocationType.EventRemove:
+ ITargetEventInfo ev = member as ITargetEventInfo;
+ if (ev == null)
+ return null;
+
+ if (type == LocationType.EventAdd) {
+ func = ev.Add;
+ } else {
+ func = ev.Remove;
+ }
+
+ return new SourceLocation (func.Source);
+ default:
+ return null;
+ }
+ }
+ }
+
+ public class PointerDereferenceExpression : PointerExpression
+ {
+ Expression expr;
+ string name;
+ bool current_ok;
+
+ public PointerDereferenceExpression (Expression expr, bool current_ok)
+ {
+ this.expr = expr;
+ this.current_ok = current_ok;
+ name = '*' + expr.Name;
+ }
+
+ public override string Name {
+ get {
+ return name;
+ }
+ }
+
+ protected override Expression DoResolve (EvaluationContext context)
+ {
+ expr = expr.Resolve (context);
+ if (expr == null)
+ return null;
+
+ resolved = true;
+ return this;
+ }
+
+ protected override ITargetType DoEvaluateType (EvaluationContext context)
+ {
+ ITargetType type = expr.EvaluateType (context);
+
+ ITargetPointerType ptype = type as ITargetPointerType;
+ if (ptype != null)
+ return ptype.StaticType;
+
+ throw new EvaluationException (
+ "Expression `{0}' is not a pointer.", expr.Name);
+ }
+
+ protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+ {
+ ITargetObject obj = expr.EvaluateVariable (context);
+
+ ITargetPointerObject pobj = obj as ITargetPointerObject;
+ if (pobj != null) {
+ if (!pobj.HasDereferencedObject)
+ throw new EvaluationException (
+ "Cannot dereference `{0}'.", expr.Name);
+
+ return pobj.DereferencedObject;
+ }
+
+ ITargetClassObject cobj = obj as ITargetClassObject;
+ if (current_ok && (cobj != null))
+ return cobj.CurrentObject;
+
+ throw new EvaluationException (
+ "Expression `{0}' is not a pointer type.", expr.Name);
+ }
+
+ public override TargetLocation EvaluateAddress (EvaluationContext context)
+ {
+ FrameHandle frame = context.CurrentFrame;
+
+ object obj = expr.Resolve (context);
+ if (obj is int)
+ obj = (long) (int) obj;
+ if (obj is long) {
+ TargetAddress taddress = new TargetAddress (
+ frame.Frame.AddressDomain, (long) obj);
+
+ return new AbsoluteTargetLocation (frame.Frame, taddress);
+ }
+
+ ITargetPointerObject pobj = obj as ITargetPointerObject;
+ if (pobj == null)
+ throw new EvaluationException (
+ "Expression `{0}' is not a pointer type.", expr.Name);
+
+ return pobj.Location;
+ }
+ }
+
+ public class AddressOfExpression : PointerExpression
+ {
+ Expression expr;
+ string name;
+
+ public AddressOfExpression (Expression expr)
+ {
+ this.expr = expr;
+ name = '&' + expr.Name;
+ }
+
+ public override string Name {
+ get {
+ return name;
+ }
+ }
+
+ protected override Expression DoResolve (EvaluationContext context)
+ {
+ expr = expr.Resolve (context);
+ if (expr == null)
+ return null;
+
+ resolved = true;
+ return this;
+ }
+
+ protected override ITargetType DoEvaluateType (EvaluationContext context)
+ {
+ FrameHandle frame = context.CurrentFrame;
+
+ ITargetPointerType ptype = expr.EvaluateType (context)
+ as ITargetPointerType;
+ if (ptype != null)
+ return ptype;
+
+ return frame.Language.PointerType;
+ }
+
+ protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+ {
+ FrameHandle frame = context.CurrentFrame;
+
+ TargetLocation location = EvaluateAddress (context);
+ return frame.Language.CreatePointer (frame.Frame, location.Address);
+ }
+
+ public override TargetLocation EvaluateAddress (EvaluationContext context)
+ {
+ ITargetObject obj = expr.EvaluateVariable (context);
+ if (!obj.Location.HasAddress)
+ throw new EvaluationException (
+ "Cannot take address of expression `{0}'", expr.Name);
+ return obj.Location;
+ }
+ }
+
+ public class ArrayAccessExpression : Expression
+ {
+ Expression expr, index;
+ string name;
+
+ public ArrayAccessExpression (Expression expr, Expression index)
+ {
+ this.expr = expr;
+ this.index = index;
+
+ name = String.Format ("{0}[{1}]", expr.Name, index);
+ }
+
+ public override string Name {
+ get {
+ return name;
+ }
+ }
+
+ protected override Expression DoResolve (EvaluationContext context)
+ {
+ expr = expr.Resolve (context);
+ if (expr == null)
+ return null;
+
+ index = index.Resolve (context);
+ if (index == null)
+ return null;
+
+ resolved = true;
+ return this;
+ }
+
+ protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+ {
+ int i;
+
+ ITargetObject obj = expr.EvaluateVariable (context);
+
+ try {
+ i = (int) this.index.Evaluate (context);
+ } catch (Exception e) {
+ throw new EvaluationException (
+ "Cannot convert {0} to an integer for indexing: {1}",
+ this.index, e);
+ }
+
+ ITargetArrayObject aobj = obj as ITargetArrayObject;
+ if (aobj == null) {
+ ITargetPointerObject pobj = obj as ITargetPointerObject;
+ if ((pobj != null) && pobj.Type.IsArray)
+ return pobj.GetArrayElement (i);
+
+ throw new EvaluationException (
+ "Variable {0} is not an array type.", expr.Name);
+ }
+
+ if ((i < aobj.LowerBound) || (i >= aobj.UpperBound)) {
+ if (aobj.UpperBound == 0)
+ throw new EvaluationException (
+ "Index {0} of array expression {1} out of bounds " +
+ "(array is of zero length)", i, expr.Name);
+ else
+ throw new EvaluationException (
+ "Index {0} of array expression {1} out of bounds " +
+ "(must be between {2} and {3}).", i, expr.Name,
+ aobj.LowerBound, aobj.UpperBound - 1);
+ }
+
+ return aobj [i];
+ }
+
+ protected override ITargetType DoEvaluateType (EvaluationContext context)
+ {
+ ITargetArrayType type = expr.EvaluateType (context)
+ as ITargetArrayType;
+ if (type == null)
+ throw new EvaluationException (
+ "Variable {0} is not an array type.", expr.Name);
+
+ return type.ElementType;
+ }
+ }
+
+ public class CastExpression : Expression
+ {
+ Expression target, expr;
+ string name;
+
+ public CastExpression (Expression target, Expression expr)
+ {
+ this.target = target;
+ this.expr = expr;
+ this.name = String.Format ("(({0}) {1})", target.Name, expr.Name);
+ }
+
+ public override string Name {
+ get {
+ return name;
+ }
+ }
+
+ protected override Expression DoResolve (EvaluationContext context)
+ {
+ target = target.ResolveType (context);
+ if (target == null)
+ return null;
+
+ expr = expr.Resolve (context);
+ if (expr == null)
+ return null;
+
+ resolved = true;
+ return this;
+ }
+
+ static ITargetClassObject TryParentCast (EvaluationContext context,
+ ITargetClassObject source,
+ ITargetClassType source_type,
+ ITargetClassType target_type)
+ {
+ if (source_type == target_type)
+ return source;
+
+ if (!source_type.HasParent)
+ return null;
+
+ source = TryParentCast (
+ context, source, source_type.ParentType, target_type);
+ if (source == null)
+ return null;
+
+ return source.Parent;
+ }
+
+ static ITargetClassObject TryCurrentCast (EvaluationContext context,
+ ITargetClassObject source,
+ ITargetClassType source_type,
+ ITargetClassType target_type)
+ {
+ ITargetClassObject current = source.CurrentObject;
+ if (current.Type == source_type)
+ return null;
+
+ return TryParentCast (context, current, current.Type, target_type);
+ }
+
+ static ITargetObject TryCast (EvaluationContext context, ITargetObject source,
+ ITargetClassType target_type)
+ {
+ if (source.TypeInfo.Type == target_type)
+ return source;
+
+ ITargetClassObject sobj = source as ITargetClassObject;
+ if (sobj == null)
+ return null;
+
+ ITargetClassObject result;
+ result = TryParentCast (context, sobj, sobj.Type, target_type);
+ if (result != null)
+ return result;
+
+ return TryCurrentCast (context, sobj, sobj.Type, target_type);
+ }
+
+ protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+ {
+ ITargetClassType type = target.EvaluateType (context)
+ as ITargetClassType;
+ if (type == null)
+ throw new EvaluationException (
+ "Variable {0} is not a class type.", target.Name);
+
+ ITargetClassObject source = expr.EvaluateVariable (context)
+ as ITargetClassObject;
+ if (source == null)
+ throw new EvaluationException (
+ "Variable {0} is not a class type.", expr.Name);
+
+ ITargetObject obj = TryCast (context, source, type);
+ if (obj == null)
+ throw new EvaluationException (
+ "Cannot cast from {0} to {1}.", source.Type.Name,
+ type.Name);
+
+ return obj;
+ }
+
+ protected override ITargetType DoEvaluateType (EvaluationContext context)
+ {
+ ITargetObject obj = EvaluateVariable (context);
+ if (obj == null)
+ return null;
+
+ return obj.TypeInfo.Type;
+ }
+ }
+
+ public class InvocationExpression : Expression
+ {
+ Expression method_expr;
+ Expression[] arguments;
+ MethodGroupExpression mg;
+ string name;
+
+ public InvocationExpression (Expression method_expr, Expression[] arguments)
+ {
+ this.method_expr = method_expr;
+ this.arguments = arguments;
+
+ name = String.Format ("{0} ()", method_expr.Name);
+ }
+
+ public override string Name {
+ get { return name; }
+ }
+
+ protected override Expression DoResolve (EvaluationContext context)
+ {
+ method_expr = method_expr.Resolve (context);
+ if (method_expr == null)
+ return null;
+
+ mg = method_expr as MethodGroupExpression;
+ if (mg == null)
+ throw new EvaluationException (
+ "Expression `{0}' is not a method.", method_expr.Name);
+
+ resolved = true;
+ return this;
+ }
+
+ protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+ {
+ return Invoke (context, false);
+ }
+
+ protected override SourceLocation DoEvaluateLocation (EvaluationContext context,
+ LocationType type, Expression[] types)
+ {
+ Expression[] argtypes = new Expression [arguments.Length];
+ for (int i = 0; i < arguments.Length; i++) {
+ argtypes [i] = arguments [i].ResolveType (context);
+ if (argtypes [i] == null)
+ return null;
+ }
+
+ return method_expr.EvaluateLocation (context, type, argtypes);
+ }
+
+ public ITargetObject Invoke (EvaluationContext context, bool debug)
+ {
+ Expression[] args = new Expression [arguments.Length];
+ for (int i = 0; i < arguments.Length; i++) {
+ args [i] = arguments [i].Resolve (context);
+ if (args [i] == null)
+ return null;
+ }
+
+ ITargetFunctionObject func = mg.EvaluateMethod (
+ context, context.CurrentFrame.Frame, args);
+
+ ITargetObject[] objs = new ITargetObject [args.Length];
+ for (int i = 0; i < args.Length; i++)
+ objs [i] = args [i].EvaluateVariable (context);
+
+ try {
+ ITargetObject retval = func.Invoke (objs, debug);
+ if (!debug && !func.Type.HasReturnValue)
+ throw new EvaluationException ("Method `{0}' doesn't return a value.", Name);
+
+ return retval;
+ } catch (Mono.Debugger.TargetInvocationException ex) {
+ throw new EvaluationException ("Invocation of `{0}' raised an exception: {1}", Name, ex.Message);
+ }
+ }
+ }
+
+ public class NewExpression : Expression
+ {
+ Expression type_expr;
+ Expression[] arguments;
+ string name;
+
+ public NewExpression (Expression type_expr, Expression[] arguments)
+ {
+ this.type_expr = type_expr;
+ this.arguments = arguments;
+
+ name = String.Format ("new {0} ()", type_expr.Name);
+ }
+
+ public override string Name {
+ get { return name; }
+ }
+
+ protected override Expression DoResolve (EvaluationContext context)
+ {
+ type_expr = type_expr.ResolveType (context);
+ if (type_expr == null)
+ return null;
+
+ for (int i = 0; i < arguments.Length; i++) {
+ arguments [i] = arguments [i].Resolve (context);
+ if (arguments [i] == null)
+ return null;
+ }
+
+ resolved = true;
+ return this;
+ }
+
+ protected override ITargetType DoEvaluateType (EvaluationContext context)
+ {
+ return type_expr.EvaluateType (context);
+ }
+
+ protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+ {
+ return Invoke (context, false);
+ }
+
+ public ITargetObject Invoke (EvaluationContext context, bool debug)
+ {
+ FrameHandle frame = context.CurrentFrame;
+
+ ITargetStructType stype = type_expr.EvaluateType (context)
+ as ITargetStructType;
+ if (stype == null)
+ throw new EvaluationException (
+ "Type `{0}' is not a struct or class.",
+ type_expr.Name);
+
+ ArrayList candidates = new ArrayList ();
+ candidates.AddRange (stype.Constructors);
+
+ ITargetMethodInfo method;
+ if (candidates.Count == 0)
+ throw new EvaluationException (
+ "Type `{0}' has no public constructor.",
+ type_expr.Name);
+ else if (candidates.Count == 1)
+ method = (ITargetMethodInfo) candidates [0];
+ else
+ method = MethodGroupExpression.OverloadResolve (
+ context, frame.Frame.Language, stype, arguments,
+ candidates);
+
+ if (method == null)
+ throw new EvaluationException (
+ "Type `{0}' has no constructor which is applicable " +
+ "for your list of arguments.", type_expr.Name);
+
+ ITargetFunctionObject ctor = stype.GetConstructor (
+ frame.Frame, method.Index);
+
+ ITargetObject[] args = new ITargetObject [arguments.Length];
+ for (int i = 0; i < arguments.Length; i++)
+ args [i] = arguments [i].EvaluateVariable (context);
+
+ try {
+ return ctor.Type.InvokeStatic (frame.Frame, args, debug);
+ } catch (Mono.Debugger.TargetInvocationException ex) {
+ throw new EvaluationException (
+ "Invocation of type `{0}'s constructor raised an " +
+ "exception: {1}", type_expr.Name, ex.Message);
+ }
+ }
+ }
+
+ public class AssignmentExpression : Expression
+ {
+ Expression left, right;
+ string name;
+
+ public AssignmentExpression (Expression left, Expression right)
+ {
+ this.left = left;
+ this.right = right;
+
+ name = left.Name + "=" + right.Name;
+ }
+
+ public override string Name {
+ get { return name; }
+ }
+
+ protected override Expression DoResolve (EvaluationContext context)
+ {
+ left = left.Resolve (context);
+ if (left == null)
+ return null;
+
+ right = right.Resolve (context);
+ if (right == null)
+ return null;
+
+ resolved = true;
+ return this;
+ }
+
+ protected override ITargetObject DoEvaluateVariable (EvaluationContext context)
+ {
+ ITargetObject obj = right.EvaluateVariable (context);
+ left.Assign (context, obj);
+ return obj;
+ }
+ }
+}
+#endif
Modified: trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Gui/DebuggerVariablePad.cs
===================================================================
--- trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Gui/DebuggerVariablePad.cs 2005-02-28 23:54:16 UTC (rev 2281)
+++ trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Gui/DebuggerVariablePad.cs 2005-03-01 23:58:20 UTC (rev 2282)
@@ -2,9 +2,11 @@
using Gtk;
using GtkSharp;
using System;
+using System.Diagnostics;
using System.IO;
using System.Collections;
using System.Globalization;
+using System.Text;
using System.Runtime.InteropServices;
using Mono.Debugger;
using Mono.Debugger.Languages;
@@ -12,11 +14,13 @@
using MonoDevelop.Core.Services;
using MonoDevelop.Services;
+using Debugger.Frontend;
+
namespace MonoDevelop.SourceEditor.Gui
{
public class DebuggerVariablePad : Gtk.ScrolledWindow
{
- StackFrame current_frame;
+ Mono.Debugger.StackFrame current_frame;
Gtk.TreeView tree;
Gtk.TreeStore store;
@@ -91,19 +95,106 @@
return inserted;
}
- bool add_struct (TreeIter parent, ITargetStructObject sobj)
+ bool add_member (TreeIter parent, ITargetStructObject sobj, ITargetMemberInfo member, bool is_field)
{
bool inserted = false;
- foreach (ITargetFieldInfo field in sobj.Type.Fields) {
+#if NET_2_0
+ DebuggerBrowsableAttribute battr = GetDebuggerBrowsableAttribute (member);
+ if (battr == null) {
TreeIter iter = store.Append (parent);
- add_object (sobj.GetField (field.Index), field.Name, iter);
+ add_object (is_field ? sobj.GetField (member.Index) : sobj.GetProperty (member.Index),
+ member.Name, iter);
inserted = true;
}
+ else {
+ TreeIter iter;
+ switch (battr.State) {
+ case DebuggerBrowsableState.Never:
+ // don't display it at all
+ continue;
+ case DebuggerBrowsableState.Collapsed:
+ // the default behavior for the debugger (c&p from above)
+ iter = store.Append (parent);
+ add_object (is_field ? sobj.GetField (member.Index) : sobj.GetProperty (member.Index),
+ member.Name, iter);
+ inserted = true;
+ break;
+ case DebuggerBrowsableState.Expanded:
+ // add it as in the Collapsed case...
+ iter = store.Append (parent);
+ add_object (is_field ? sobj.GetField (member.Index) : sobj.GetProperty (member.Index),
+ member.Name, iter);
+ inserted = true;
+ // then expand the row
+ tree.ExpandRow (store.GetPath (iter), false);
+ break;
+ case DebuggerBrowsableState.RootHidden:
+ ITargetObject member_obj = is_field ? sobj.GetField (member.Index) : sobj.GetProperty (member.Index);
+
+ if (member_obj != null) {
+ switch (member_obj.TypeInfo.Type.Kind) {
+ case TargetObjectKind.Array:
+ iter = store.Append (parent);
+ // handle arrays normally, should check how vs2005 does this.
+ add_object (member_obj, member.Name, iter);
+ inserted = true;
+ break;
+ case TargetObjectKind.Class:
+ try {
+ add_class (parent, (ITargetClassObject)member_obj);
+ inserted = true;
+ }
+ catch {
+ // what about this case? where the member is possibly
+ // uninitialized, do we try to add it later?
+ }
+ break;
+ case TargetObjectKind.Struct:
+ try {
+ add_struct (parent, (ITargetStructObject)member_obj);
+ inserted = true;
+ }
+ catch {
+ // what about this case? where the member is possibly
+ // uninitialized, do we try to add it later?
+ }
+ break;
+ default:
+ // nothing
+ break;
+ }
+ }
+ break;
+ }
+ }
+#else
+ TreeIter iter = store.Append (parent);
+ add_object (sobj.GetField (member.Index), member.Name, iter);
+ inserted = true;
+#endif
+
return inserted;
}
+ bool add_struct (TreeIter parent, ITargetStructObject sobj)
+ {
+ bool inserted = false;
+
+ foreach (ITargetFieldInfo field in sobj.Type.Fields) {
+ if (add_member (parent, sobj, field, true))
+ inserted = true;
+ }
+
+ foreach (ITargetPropertyInfo prop in sobj.Type.Properties) {
+ if (add_member (parent, sobj, prop, false))
+ inserted = true;
+ }
+
+ return inserted;
+ }
+
bool add_class (TreeIter parent, ITargetClassObject sobj)
{
bool inserted = false;
@@ -198,6 +289,104 @@
iters.Add (parent, obj);
}
+#if NET_2_0
+ DebuggerBrowsableAttribute GetDebuggerBrowsableAttribute (ITargetMemberInfo info)
+ {
+ if (info.Handle != null && info.Handle is System.Reflection.MemberInfo) {
+ System.Reflection.MemberInfo mi = (System.Reflection.MemberInfo)info.Handle;
+ object[] attrs = mi.GetCustomAttributes (typeof (DebuggerBrowsableAttribute), false);
+
+ if (attrs != null && attrs.Length > 0)
+ return (DebuggerBrowsableAttribute)attrs[0];
+ }
+
+ return null;
+ }
+
+ DebuggerDisplayAttribute GetDebuggerDisplayAttribute (ITargetObject obj)
+ {
+ if (obj.TypeInfo.Type.TypeHandle != null && obj.TypeInfo.Type.TypeHandle is Type) {
+ Type t = (Type)obj.TypeInfo.Type.TypeHandle;
+ object[] attrs = t.GetCustomAttributes (typeof (DebuggerDisplayAttribute), false);
+
+ if (attrs != null && attrs.Length > 0)
+ return (DebuggerDisplayAttribute)attrs[0];
+ }
+
+ return null;
+ }
+
+ string EvaluateDebuggerDisplay (ITargetObject obj, string display)
+ {
+ StringBuilder sb = new StringBuilder ("");
+ DebuggingService dbgr = (DebuggingService)ServiceManager.GetService (typeof (DebuggingService));
+ EvaluationContext ctx = new EvaluationContext (obj);
+
+ ctx.CurrentProcess = new ProcessHandle (dbgr.MainThread);
+
+ /* break up the string into runs of {...} and
+ * normal text. treat the {...} as C#
+ * expressions, and evaluate them */
+ int start_idx = 0;
+
+ while (true) {
+ int left_idx;
+ int right_idx;
+ left_idx = display.IndexOf ('{', start_idx);
+
+ if (left_idx == -1) {
+ /* we're done. */
+ sb.Append (display.Substring (start_idx));
+ break;
+ }
+ if (left_idx != start_idx) {
+ sb.Append (display.Substring (start_idx, left_idx - start_idx));
+ }
+ right_idx = display.IndexOf ('}', left_idx + 1);
+ if (right_idx == -1) {
+ // '{...\0'. ignore the '{', append the rest, and break out */
+ sb.Append (display.Substring (left_idx + 1));
+ break;
+ }
+
+ if (right_idx - left_idx > 1) {
+ // there's enough space for an
+ // expression. parse it and see
+ // what we get.
+
+ string snippet = display.Substring (left_idx + 1, right_idx - left_idx - 1);
+
+ CSharpExpressionParser parser = new CSharpExpressionParser (ctx, snippet);
+ Expression expr = parser.Parse (snippet);
+
+ expr = expr.Resolve (ctx);
+ object retval = expr.Evaluate (ctx);
+
+#region "c&p'ed from debugger/frontend/Style.cs"
+ if (retval is long) {
+ sb.Append (String.Format ("0x{0:x}", (long) retval));
+ }
+ else if (retval is string) {
+ sb.Append ('"' + (string) retval + '"');
+ }
+ else if (retval is ITargetObject) {
+ ITargetObject tobj = (ITargetObject) retval;
+ sb.Append (tobj.Print ());
+ }
+ else {
+ sb.Append (retval.ToString ());
+ }
+#endregion
+ }
+
+
+ start_idx = right_idx + 1;
+ }
+
+ return sb.ToString ();
+ }
+#endif
+
void add_object (ITargetObject obj, string name, TreeIter iter)
{
AmbienceService amb = (AmbienceService)MonoDevelop.Core.Services.ServiceManager.GetService (typeof (AmbienceService));
@@ -211,8 +400,16 @@
break;
case TargetObjectKind.Array:
+ add_data (obj, iter);
+ break;
case TargetObjectKind.Struct:
case TargetObjectKind.Class:
+#if NET_2_0
+ DebuggerDisplayAttribute dattr = GetDebuggerDisplayAttribute (obj);
+ if (dattr != null)
+ store.SetValue (iter, 2,
+ new GLib.Value (EvaluateDebuggerDisplay (obj, dattr.Value)));
+#endif
add_data (obj, iter);
break;
}
@@ -281,7 +478,7 @@
protected void OnPausedEvent (object o, EventArgs args)
{
DebuggingService dbgr = (DebuggingService)ServiceManager.GetService (typeof (DebuggingService));
- current_frame = (StackFrame)dbgr.CurrentFrame;
+ current_frame = (Mono.Debugger.StackFrame)dbgr.CurrentFrame;
UpdateDisplay ();
}
}
Modified: trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Makefile.am
===================================================================
--- trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Makefile.am 2005-02-28 23:54:16 UTC (rev 2281)
+++ trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/Makefile.am 2005-03-01 23:58:20 UTC (rev 2282)
@@ -11,6 +11,11 @@
FILES = \
DebuggerCommands.cs \
DebuggingService.cs \
+EvaluationContext.cs \
+Expression.cs \
+CSharpTokenizer.cs \
+CSharpExpressionParser.cs \
+MyTextReader.cs \
Gui/DebuggerLocalsPad.cs \
Gui/DebuggerVariablePad.cs \
Gui/DebuggerStackTracePad.cs \
Added: trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/MyTextReader.cs
===================================================================
--- trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/MyTextReader.cs 2005-02-28 23:54:16 UTC (rev 2281)
+++ trunk/MonoDevelop/Core/src/AddIns/DebuggerAddIn/MyTextReader.cs 2005-03-01 23:58:20 UTC (rev 2282)
@@ -0,0 +1,76 @@
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace Debugger.Frontend
+{
+ internal class MyTextReader : TextReader
+ {
+ bool closed = false;
+ string current_line = null;
+ int pos = 0;
+
+ public string Text {
+ set {
+ if (closed)
+ throw new InvalidOperationException ("Reader is closed.");
+
+ pos = 0;
+ current_line = value;
+ }
+ }
+
+ bool check_line ()
+ {
+ if (closed || (current_line == null))
+ return false;
+
+ if (pos >= current_line.Length) {
+ current_line = null;
+ return false;
+ }
+
+ return true;
+ }
+
+ public override int Peek ()
+ {
+ if (!check_line ())
+ return -1;
+
+ return current_line [pos];
+ }
+
+ public override int Read ()
+ {
+ if (!check_line ())
+ return -1;
+
+ return current_line [pos++];
+ }
+
+ public override string ReadLine ()
+ {
+ string retval;
+
+ if (!check_line ())
+ return String.Empty;
+
+ retval = current_line;
+ current_line = null;
+ return retval;
+ }
+
+ public override string ReadToEnd ()
+ {
+ return ReadLine ();
+ }
+
+ public override void Close ()
+ {
+ current_line = null;
+ closed = true;
+ base.Close ();
+ }
+ }
+}
More information about the Monodevelop-patches-list
mailing list