Merge pull request #439 from mono-soc-2012/garyb/iconfix
[mono.git] / mcs / class / Mono.CodeContracts / Mono.CodeContracts.Static.Analysis.ExpressionAnalysis.Decoding / FullExpressionDecoder.cs
1 // 
2 // FullExpressionDecoder.cs
3 // 
4 // Authors:
5 //      Alexander Chebaturkin (chebaturkin@gmail.com)
6 // 
7 // Copyright (C) 2011 Alexander Chebaturkin
8 // 
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //  
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 // 
28
29 using System;
30 using System.Collections.Generic;
31 using Mono.CodeContracts.Static.AST;
32 using Mono.CodeContracts.Static.Analysis.HeapAnalysis.Paths;
33 using Mono.CodeContracts.Static.Analysis.Numerical;
34 using Mono.CodeContracts.Static.DataStructures;
35 using Mono.CodeContracts.Static.Lattices;
36 using Mono.CodeContracts.Static.Providers;
37
38 namespace Mono.CodeContracts.Static.Analysis.ExpressionAnalysis.Decoding {
39         class FullExpressionDecoder<V, E> : IFullExpressionDecoder<V, E>
40                 where V : IEquatable<V>
41                 where E : IEquatable<E> {
42                 public readonly VisitorForIsBinaryExpression<V, E> BinaryExpressionVisitor;
43                 public readonly VisitorForIsInst<V, E> IsInstVisitor;
44                 public readonly VisitorForIsNull<V, E> IsNullVisitor;
45                 public readonly VisitorForSizeOf<V, E> SizeOfVisitor;
46                 public readonly VisitorForIsUnaryExpression<V, E> UnaryExpressionVisitor;
47                 public readonly VisitorForUnderlyingVariable<V, E> UnderlyingVariableVisitor;
48                 public readonly VisitorForValueOf<V, E> ValueOfVisitor;
49                 public readonly VisitorForVariable<V, E> VariableVisitor;
50                 public readonly VisitorForVariablesIn<V, E> VariablesInVisitor;
51                 protected readonly IMetaDataProvider MetaDataProvider;
52
53                 #region Implementation of IFullExpressionDecoder<V,E>
54                 public bool IsVariable (E expr, out object variable)
55                 {
56                         V var;
57                         bool res = VisitorForVariable<V, E>.IsVariable (expr, out var, this);
58
59                         variable = var;
60                         return res;
61                 }
62
63                 public V UnderlyingVariable (E expr)
64                 {
65                         return VisitorForUnderlyingVariable<V, E>.IsUnderlyingVariable (expr, this);
66                 }
67
68                 public bool IsNull (E expr)
69                 {
70                         return VisitorForIsNull<V, E>.IsNull (expr, this);
71                 }
72
73                 public bool IsConstant (E expr, out object value, out TypeNode type)
74                 {
75                         return VisitorForValueOf<V, E>.IsConstant (expr, out value, out type, this);
76                 }
77
78                 public bool IsSizeof (E expr, out TypeNode type)
79                 {
80                         return VisitorForSizeOf<V, E>.IsSizeOf (expr, out type, this);
81                 }
82
83                 public bool IsIsinst (E expr, out E arg, out TypeNode type)
84                 {
85                         return VisitorForIsInst<V, E>.IsIsInst (expr, out type, out arg, this);
86                 }
87
88                 public bool IsUnaryExpression (E expr, out UnaryOperator op, out E arg)
89                 {
90                         return VisitorForIsUnaryExpression<V, E>.IsUnary (expr, out op, out arg, this);
91                 }
92
93                 public bool IsBinaryExpression (E expr, out BinaryOperator op, out E left, out E right)
94                 {
95                         return VisitorForIsBinaryExpression<V, E>.IsBinary (expr, out op, out left, out right, this);
96                 }
97
98                 public void AddFreeVariables (E expr, ISet<E> set)
99                 {
100                         VisitorForVariablesIn<V, E>.AddFreeVariables (expr, set, this);
101                 }
102
103                 public Sequence<PathElement> GetVariableAccessPath (E expr)
104                 {
105                         return ContextProvider.ValueContext.AccessPathList (ContextProvider.ExpressionContext.GetPC (expr), ContextProvider.ExpressionContext.Unrefine (expr), true, false);
106                 }
107
108                 public bool TryGetType (E expr, out TypeNode type)
109                 {
110                         FlatDomain<TypeNode> aType = ContextProvider.ExpressionContext.GetType (expr);
111                         if (aType.IsNormal()) {
112                                 type = aType.Value;
113                                 return true;
114                         }
115
116                         type = null;
117                         return false;
118                 }
119
120                 public bool TrySizeOfAsConstant (E expr, out int sizeAsConstant)
121                 {
122                         return TrySizeOf (expr, out sizeAsConstant);
123                 }
124
125             private bool TrySizeOf (E expr, out int sizeAsConstant)
126                 {
127                         TypeNode type;
128                         if (VisitorForSizeOf<V, E>.IsSizeOf (expr, out type, this)) {
129                                 int size = this.MetaDataProvider.TypeSize (type);
130                                 if (size != -1) {
131                                         sizeAsConstant = size;
132                                         return true;
133                                 }
134                         }
135
136                         sizeAsConstant = -1;
137                         return false;
138                 }
139                 #endregion
140
141                 public FullExpressionDecoder (IMetaDataProvider metaDataProvider, IExpressionContextProvider<E, V> contextProvider)
142                 {
143                         ContextProvider = contextProvider;
144                         this.MetaDataProvider = metaDataProvider;
145                         this.VariableVisitor = new VisitorForVariable<V, E> ();
146                         this.UnderlyingVariableVisitor = new VisitorForUnderlyingVariable<V, E> ();
147                         this.UnaryExpressionVisitor = new VisitorForIsUnaryExpression<V, E> ();
148                         this.BinaryExpressionVisitor = new VisitorForIsBinaryExpression<V, E> ();
149                         this.VariablesInVisitor = new VisitorForVariablesIn<V, E> (contextProvider);
150                         this.ValueOfVisitor = new VisitorForValueOf<V, E> ();
151                         this.SizeOfVisitor = new VisitorForSizeOf<V, E> ();
152                         this.IsInstVisitor = new VisitorForIsInst<V, E> ();
153                         this.IsNullVisitor = new VisitorForIsNull<V, E> ();
154                 }
155
156                 public IExpressionContextProvider<E, V> ContextProvider { get; private set; }
157         }
158 }