~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to src/core/Mono.Debugging/Mono.Debugging.Evaluation/ObjectValueAdaptor.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// 
 
2
// ObjectValueAdaptor.cs
 
3
//  
 
4
// Authors: Lluis Sanchez Gual <lluis@novell.com>
 
5
//          Jeffrey Stedfast <jeff@xamarin.com>
 
6
// 
 
7
// Copyright (c) 2008 Novell, Inc (http://www.novell.com)
 
8
// Copyright (c) 2012 Xamarin Inc. (http://www.xamarin.com)
 
9
// 
 
10
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
11
// of this software and associated documentation files (the "Software"), to deal
 
12
// in the Software without restriction, including without limitation the rights
 
13
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
14
// copies of the Software, and to permit persons to whom the Software is
 
15
// furnished to do so, subject to the following conditions:
 
16
// 
 
17
// The above copyright notice and this permission notice shall be included in
 
18
// all copies or substantial portions of the Software.
 
19
// 
 
20
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
21
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
22
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
23
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
24
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
25
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
26
// THE SOFTWARE.
 
27
 
1
28
using System;
2
 
using System.Collections.Generic;
3
29
using System.Linq;
4
30
using System.Text;
5
31
using System.Reflection;
 
32
using System.Diagnostics;
 
33
using System.Collections.Generic;
 
34
 
6
35
using Mono.Debugging.Client;
7
36
using Mono.Debugging.Backend;
8
 
using System.Diagnostics;
9
 
using System.Collections;
10
37
 
11
38
namespace Mono.Debugging.Evaluation
12
39
{
64
91
                {
65
92
                        try {
66
93
                                return CreateObjectValueImpl (ctx, source, path, obj, flags);
 
94
                        } catch (EvaluatorAbortedException ex) {
 
95
                                return ObjectValue.CreateFatalError (path.LastName, ex.Message, flags);
 
96
                        } catch (EvaluatorException ex) {
 
97
                                return ObjectValue.CreateFatalError (path.LastName, ex.Message, flags);
67
98
                        } catch (Exception ex) {
68
99
                                ctx.WriteDebuggerError (ex);
69
100
                                return ObjectValue.CreateFatalError (path.LastName, ex.Message, flags);
245
276
                public abstract bool IsString (EvaluationContext ctx, object val);
246
277
                public abstract bool IsArray (EvaluationContext ctx, object val);
247
278
                public abstract bool IsEnum (EvaluationContext ctx, object val);
 
279
                public abstract bool IsValueType (object type);
248
280
                public abstract bool IsClass (object type);
249
281
                public abstract object TryCast (EvaluationContext ctx, object val, object type);
250
282
 
251
283
                public abstract object GetValueType (EvaluationContext ctx, object val);
252
 
                public abstract string GetTypeName (EvaluationContext ctx, object val);
 
284
                public abstract string GetTypeName (EvaluationContext ctx, object type);
253
285
                public abstract object[] GetTypeArgs (EvaluationContext ctx, object type);
254
286
                public abstract object GetBaseType (EvaluationContext ctx, object type);
 
287
 
 
288
                public virtual bool IsNullableType (EvaluationContext ctx, object type)
 
289
                {
 
290
                        return type != null && GetTypeName (ctx, type).StartsWith ("System.Nullable`1", StringComparison.Ordinal);
 
291
                }
 
292
 
 
293
                public virtual bool NullableHasValue (EvaluationContext ctx, object type, object obj)
 
294
                {
 
295
                        ValueReference hasValue = GetMember (ctx, type, obj, "HasValue");
 
296
 
 
297
                        return (bool) hasValue.ObjectValue;
 
298
                }
 
299
 
 
300
                public virtual ValueReference NullableGetValue (EvaluationContext ctx, object type, object obj)
 
301
                {
 
302
                        return GetMember (ctx, type, obj, "Value");
 
303
                }
255
304
                
256
305
                public virtual bool IsFlagsEnumType (EvaluationContext ctx, object type)
257
306
                {
275
324
                public object GetBaseType (EvaluationContext ctx, object type, bool includeObjectClass)
276
325
                {
277
326
                        object bt = GetBaseType (ctx, type);
278
 
                        string tn = GetTypeName (ctx, bt);
 
327
                        string tn = bt != null ? GetTypeName (ctx, bt) : null;
279
328
                        if (!includeObjectClass && bt != null && (tn == "System.Object" || tn == "System.ValueType"))
280
329
                                return null;
281
330
                        else
308
357
                {
309
358
                        return default (object);
310
359
                }
 
360
 
 
361
                public virtual bool IsTypeLoaded (EvaluationContext ctx, string typeName)
 
362
                {
 
363
                        object t = GetType (ctx, typeName);
 
364
 
 
365
                        if (t == null)
 
366
                                return false;
 
367
 
 
368
                        return IsTypeLoaded (ctx, t);
 
369
                }
 
370
 
 
371
                public virtual bool IsTypeLoaded (EvaluationContext ctx, object type)
 
372
                {
 
373
                        return true;
 
374
                }
311
375
                
312
376
                public virtual object ForceLoadType (EvaluationContext ctx, string typeName)
313
377
                {
314
 
                        return GetType (ctx, typeName);
 
378
                        object t = GetType (ctx, typeName);
 
379
 
 
380
                        if (t == null || IsTypeLoaded (ctx, t))
 
381
                                return t;
 
382
 
 
383
                        if (ForceLoadType (ctx, t))
 
384
                                return t;
 
385
 
 
386
                        return null;
 
387
                }
 
388
 
 
389
                public virtual bool ForceLoadType (EvaluationContext ctx, object type)
 
390
                {
 
391
                        return true;
315
392
                }
316
393
 
317
394
                public abstract object CreateValue (EvaluationContext ctx, object value);
337
414
 
338
415
                protected virtual ObjectValue CreateObjectValueImpl (EvaluationContext ctx, Mono.Debugging.Backend.IObjectValueSource source, ObjectPath path, object obj, ObjectValueFlags flags)
339
416
                {
340
 
                        string typeName = obj != null ? GetValueTypeName (ctx, obj) : "";
 
417
                        object type = obj != null ? GetValueType (ctx, obj) : null;
 
418
                        string typeName = type != null ? GetTypeName (ctx, type) : "";
341
419
 
342
420
                        if (obj == null || IsNull (ctx, obj)) {
343
421
                                return ObjectValue.CreateNullObject (source, path, GetDisplayTypeName (typeName), flags);
349
427
                                return ObjectValue.CreateObject (source, path, GetDisplayTypeName (typeName), ctx.Evaluator.TargetObjectToExpression (ctx, obj), flags, null);
350
428
                        }
351
429
                        else {
352
 
                                TypeDisplayData tdata = GetTypeDisplayData (ctx, GetValueType (ctx, obj));
353
 
                                
354
 
                                EvaluationResult tvalue;
355
 
                                if (!string.IsNullOrEmpty (tdata.ValueDisplayString) && ctx.Options.AllowDisplayStringEvaluation)
356
 
                                        tvalue = new EvaluationResult (EvaluateDisplayString (ctx, obj, tdata.ValueDisplayString));
357
 
                                else
358
 
                                        tvalue = ctx.Evaluator.TargetObjectToExpression (ctx, obj);
359
 
                                
 
430
                                EvaluationResult tvalue = null;
 
431
                                TypeDisplayData tdata = null;
360
432
                                string tname;
361
 
                                if (!string.IsNullOrEmpty (tdata.TypeDisplayString) && ctx.Options.AllowDisplayStringEvaluation)
362
 
                                        tname = EvaluateDisplayString (ctx, obj, tdata.TypeDisplayString);
363
 
                                else
 
433
 
 
434
                                if (IsNullableType (ctx, type)) {
 
435
                                        if (NullableHasValue (ctx, type, obj)) {
 
436
                                                ValueReference value = NullableGetValue (ctx, type, obj);
 
437
 
 
438
                                                tdata = GetTypeDisplayData (ctx, value.Type);
 
439
                                                obj = value.Value;
 
440
                                        } else {
 
441
                                                tdata = GetTypeDisplayData (ctx, type);
 
442
                                                tvalue = new EvaluationResult ("null");
 
443
                                        }
 
444
 
364
445
                                        tname = GetDisplayTypeName (typeName);
365
 
                                
 
446
                                } else {
 
447
                                        tdata = GetTypeDisplayData (ctx, type);
 
448
 
 
449
                                        if (!string.IsNullOrEmpty (tdata.TypeDisplayString) && ctx.Options.AllowDisplayStringEvaluation)
 
450
                                                tname = EvaluateDisplayString (ctx, obj, tdata.TypeDisplayString);
 
451
                                        else
 
452
                                                tname = GetDisplayTypeName (typeName);
 
453
                                }
 
454
 
 
455
                                if (tvalue == null) {
 
456
                                        if (!string.IsNullOrEmpty (tdata.ValueDisplayString) && ctx.Options.AllowDisplayStringEvaluation)
 
457
                                                tvalue = new EvaluationResult (EvaluateDisplayString (ctx, obj, tdata.ValueDisplayString));
 
458
                                        else
 
459
                                                tvalue = ctx.Evaluator.TargetObjectToExpression (ctx, obj);
 
460
                                }
 
461
 
366
462
                                ObjectValue oval = ObjectValue.CreateObject (source, path, tname, tvalue, flags, null);
367
463
                                if (!string.IsNullOrEmpty (tdata.NameDisplayString) && ctx.Options.AllowDisplayStringEvaluation)
368
464
                                        oval.Name = EvaluateDisplayString (ctx, obj, tdata.NameDisplayString);
369
465
                                return oval;
370
466
                        }
371
467
                }
372
 
 
 
468
                
373
469
                public ObjectValue[] GetObjectValueChildren (EvaluationContext ctx, IObjectSource objectSource, object obj, int firstItemIndex, int count)
374
470
                {
375
471
                        return GetObjectValueChildren (ctx, objectSource, GetValueType (ctx, obj), obj, firstItemIndex, count, true);
388
484
                        if (IsPrimitive (ctx, obj))
389
485
                                return new ObjectValue[0];
390
486
 
 
487
                        if (IsNullableType (ctx, type)) {
 
488
                                if (NullableHasValue (ctx, type, obj)) {
 
489
                                        ValueReference value = NullableGetValue (ctx, type, obj);
 
490
 
 
491
                                        return GetObjectValueChildren (ctx, objectSource, value.Type, value.Value, firstItemIndex, count, dereferenceProxy);
 
492
                                } else {
 
493
                                        return new ObjectValue[0];
 
494
                                }
 
495
                        }
 
496
 
391
497
                        bool showRawView = false;
392
498
                        
393
499
                        // If there is a proxy, it has to show the members of the proxy
607
713
                                                        CompletionData data = new CompletionData ();
608
714
                                                        foreach (ValueReference cv in vr.GetChildReferences (ctx.Options))
609
715
                                                                data.Items.Add (new CompletionItem (cv.Name, cv.Flags));
610
 
                                                        data.ExpressionLenght = 0;
 
716
                                                        data.ExpressionLength = 0;
611
717
                                                        return data;
612
718
                                                }
613
719
                                        } catch (Exception ex) {
630
736
                                string partialWord = exp.Substring (i+1);
631
737
                                
632
738
                                CompletionData data = new CompletionData ();
633
 
                                data.ExpressionLenght = partialWord.Length;
 
739
                                data.ExpressionLength = partialWord.Length;
634
740
                                
635
741
                                // Local variables
636
742
                                
637
743
                                foreach (ValueReference vc in GetLocalVariables (ctx))
638
 
                                        if (vc.Name.StartsWith (partialWord))
 
744
                                        if (vc.Name.StartsWith (partialWord, StringComparison.InvariantCulture))
639
745
                                                data.Items.Add (new CompletionItem (vc.Name, vc.Flags));
640
746
                                
641
747
                                // Parameters
642
748
                                
643
749
                                foreach (ValueReference vc in GetParameters (ctx))
644
 
                                        if (vc.Name.StartsWith (partialWord))
 
750
                                        if (vc.Name.StartsWith (partialWord, StringComparison.InvariantCulture))
645
751
                                                data.Items.Add (new CompletionItem (vc.Name, vc.Flags));
646
752
                                
647
753
                                // Members
654
760
                                object type = GetEnclosingType (ctx);
655
761
                                
656
762
                                foreach (ValueReference vc in GetMembers (ctx, null, type, thisobj != null ? thisobj.Value : null))
657
 
                                        if (vc.Name.StartsWith (partialWord))
 
763
                                        if (vc.Name.StartsWith (partialWord, StringComparison.InvariantCulture))
658
764
                                                data.Items.Add (new CompletionItem (vc.Name, vc.Flags));
659
765
                                
660
766
                                if (data.Items.Count > 0)
736
842
                {
737
843
                        yield break;
738
844
                }
 
845
 
 
846
                public virtual object GetParentType (EvaluationContext ctx, object type)
 
847
                {
 
848
                        if ((type is Type))
 
849
                                return ((Type) type).DeclaringType;
 
850
 
 
851
                        var name = GetTypeName (ctx, type);
 
852
                        int plus = name.LastIndexOf ('+');
 
853
 
 
854
                        return plus != -1 ? GetType (ctx, name.Substring (0, plus)) : null;
 
855
                }
739
856
                
740
857
                public virtual object CreateArray (EvaluationContext ctx, object type, object[] values)
741
858
                {
815
932
                
816
933
                public virtual object TargetObjectToObject (EvaluationContext ctx, object obj)
817
934
                {
818
 
                        if (IsNull (ctx, obj)) {
 
935
                        if (IsNull (ctx, obj))
819
936
                                return null;
820
 
                        } else if (IsArray (ctx, obj)) {
 
937
 
 
938
                        if (IsArray (ctx, obj)) {
821
939
                                ICollectionAdaptor adaptor = CreateArrayAdaptor (ctx, obj);
822
940
                                string ename = GetDisplayTypeName (GetTypeName (ctx, adaptor.ElementType));
823
941
                                int[] dims = adaptor.GetDimensions ();
833
951
                                i = ename.IndexOf ('[', i);
834
952
                                if (i != -1)
835
953
                                        return new EvaluationResult ("{" + ename.Substring (0, i) + tn + ename.Substring (i) + "}");
836
 
                                else
837
 
                                        return new EvaluationResult ("{" + ename + tn + "}");
 
954
 
 
955
                                return new EvaluationResult ("{" + ename + tn + "}");
838
956
                        }
839
 
                        else if (IsEnum (ctx, obj)) {
 
957
 
 
958
                        if (IsEnum (ctx, obj)) {
840
959
                                object type = GetValueType (ctx, obj);
841
960
                                object longType = GetType (ctx, "System.Int64");
842
961
                                object c = Cast (ctx, obj, longType);
860
979
                                                }
861
980
                                        }
862
981
                                }
 
982
 
863
983
                                if (IsFlagsEnumType (ctx, type) && rest == 0 && composed.Length > 0)
864
984
                                        return new EvaluationResult (composed, composedDisplay);
865
 
                                else
866
 
                                        return new EvaluationResult (val.ToString ());
 
985
 
 
986
                                return new EvaluationResult (val.ToString ());
867
987
                        }
868
 
                        else if (GetValueTypeName (ctx, obj) == "System.Decimal") {
 
988
 
 
989
                        if (GetValueTypeName (ctx, obj) == "System.Decimal") {
869
990
                                string res = CallToString (ctx, obj);
870
991
                                // This returns the decimal formatted using the current culture. It has to be converted to invariant culture.
871
992
                                decimal dec = decimal.Parse (res);
872
993
                                res = dec.ToString (System.Globalization.CultureInfo.InvariantCulture);
873
994
                                return new EvaluationResult (res);
874
995
                        }
875
 
                        else if (IsClassInstance (ctx, obj)) {
 
996
 
 
997
                        if (IsClassInstance (ctx, obj)) {
876
998
                                TypeDisplayData tdata = GetTypeDisplayData (ctx, GetValueType (ctx, obj));
877
999
                                if (!string.IsNullOrEmpty (tdata.ValueDisplayString) && ctx.Options.AllowDisplayStringEvaluation)
878
1000
                                        return new EvaluationResult (EvaluateDisplayString (ctx, obj, tdata.ValueDisplayString));
879
1001
 
880
1002
                                // Return the type name
881
 
                                if (ctx.Options.AllowToStringCalls)
882
 
                                        return new EvaluationResult ("{" + CallToString (ctx, obj) + "}");
 
1003
                                if (ctx.Options.AllowToStringCalls) {
 
1004
                                        try {
 
1005
                                                return new EvaluationResult ("{" + CallToString (ctx, obj) + "}");
 
1006
                                        } catch (TimeOutException) {
 
1007
                                                // ToString() timed out, fall back to default behavior.
 
1008
                                        }
 
1009
                                }
883
1010
                                
884
1011
                                if (!string.IsNullOrEmpty (tdata.TypeDisplayString) && ctx.Options.AllowDisplayStringEvaluation)
885
1012
                                        return new EvaluationResult ("{" + EvaluateDisplayString (ctx, obj, tdata.TypeDisplayString) + "}");
894
1021
                {
895
1022
                        if (obj == null)
896
1023
                                return null;
 
1024
 
897
1025
                        object res = TryConvert (ctx, obj, targetType);
898
1026
                        if (res != null)
899
1027
                                return res;
900
 
                        else
901
 
                                throw new EvaluatorException ("Can't convert an object of type '{0}' to type '{1}'", GetValueTypeName (ctx, obj), GetTypeName (ctx, targetType));
 
1028
 
 
1029
                        throw new EvaluatorException ("Can't convert an object of type '{0}' to type '{1}'", GetValueTypeName (ctx, obj), GetTypeName (ctx, targetType));
902
1030
                }
903
1031
 
904
1032
                public virtual object TryConvert (EvaluationContext ctx, object obj, object targetType)
910
1038
                {
911
1039
                        if (obj == null)
912
1040
                                return null;
 
1041
 
913
1042
                        object res = TryCast (ctx, obj, targetType);
914
1043
                        if (res != null)
915
1044
                                return res;
916
 
                        else
917
 
                                throw new EvaluatorException ("Can't cast an object of type '{0}' to type '{1}'", GetValueTypeName (ctx, obj), GetTypeName (ctx, targetType));
 
1045
 
 
1046
                        throw new EvaluatorException ("Can't cast an object of type '{0}' to type '{1}'", GetValueTypeName (ctx, obj), GetTypeName (ctx, targetType));
918
1047
                }
919
1048
 
920
1049
                public virtual string CallToString (EvaluationContext ctx, object obj)
991
1120
                public string EvaluateDisplayString (EvaluationContext ctx, object obj, string exp)
992
1121
                {
993
1122
                        StringBuilder sb = new StringBuilder ();
 
1123
                        int i = exp.IndexOf ("{");
994
1124
                        int last = 0;
995
 
                        int i = exp.IndexOf ("{");
 
1125
 
996
1126
                        while (i != -1 && i < exp.Length) {
997
1127
                                sb.Append (exp.Substring (last, i - last));
998
1128
                                i++;
 
1129
 
999
1130
                                int j = exp.IndexOf ("}", i);
1000
1131
                                if (j == -1)
1001
1132
                                        return exp;
 
1133
 
1002
1134
                                string mem = exp.Substring (i, j - i).Trim ();
1003
1135
                                if (mem.Length == 0)
1004
1136
                                        return exp;
1016
1148
                                }
1017
1149
                                
1018
1150
                                if (member != null) {
1019
 
                                        sb.Append (ctx.Evaluator.TargetObjectToString (ctx, val));
 
1151
                                        var str = ctx.Evaluator.TargetObjectToString (ctx, val);
 
1152
                                        if (str == null)
 
1153
                                                sb.Append ("null");
 
1154
                                        else
 
1155
                                                sb.Append (str);
1020
1156
                                } else {
1021
1157
                                        sb.Append ("{Unknown member '" + mem + "'}");
1022
1158
                                }
 
1159
 
1023
1160
                                last = j + 1;
1024
1161
                                i = exp.IndexOf ("{", last);
1025
1162
                        }
 
1163
 
1026
1164
                        sb.Append (exp.Substring (last));
 
1165
 
1027
1166
                        return sb.ToString ();
1028
1167
                }
1029
1168
 
1171
1310
                                
1172
1311
                                if (tn != null)
1173
1312
                                        oval.Name += " (" + ctx.Adapter.GetDisplayTypeName (ctx, tn) + ")";
1174
 
                                if (!other.Key.Name.EndsWith (")")) {
 
1313
                                if (!other.Key.Name.EndsWith (")", StringComparison.Ordinal)) {
1175
1314
                                        tn = other.Value.DeclaringType;
1176
1315
                                        if (tn != null)
1177
1316
                                                other.Key.Name += " (" + ctx.Adapter.GetDisplayTypeName (ctx, tn) + ")";