Update mcs/class/Commons.Xml.Relaxng/Commons.Xml.Relaxng/RelaxngPattern.cs
[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.DataStructures;
34 using Mono.CodeContracts.Static.Lattices;
35 using Mono.CodeContracts.Static.Providers;
36
37 namespace Mono.CodeContracts.Static.Analysis.ExpressionAnalysis.Decoding {
38         class FullExpressionDecoder<V, E> : IFullExpressionDecoder<V, E>
39                 where V : IEquatable<V>
40                 where E : IEquatable<E> {
41                 public readonly VisitorForIsBinaryExpression<V, E> BinaryExpressionVisitor;
42                 public readonly VisitorForIsInst<V, E> IsInstVisitor;
43                 public readonly VisitorForIsNull<V, E> IsNullVisitor;
44                 public readonly VisitorForSizeOf<V, E> SizeOfVisitor;
45                 public readonly VisitorForIsUnaryExpression<V, E> UnaryExpressionVisitor;
46                 public readonly VisitorForUnderlyingVariable<V, E> UnderlyingVariableVisitor;
47                 public readonly VisitorForValueOf<V, E> ValueOfVisitor;
48                 public readonly VisitorForVariable<V, E> VariableVisitor;
49                 public readonly VisitorForVariablesIn<V, E> VariablesInVisitor;
50                 private readonly IMetaDataProvider meta_data_provider;
51
52                 #region Implementation of IFullExpressionDecoder<V,E>
53                 public bool IsVariable (E expr, out object variable)
54                 {
55                         V var;
56                         bool res = VisitorForVariable<V, E>.IsVariable (expr, out var, this);
57
58                         variable = var;
59                         return res;
60                 }
61
62                 public V UnderlyingVariable (E expr)
63                 {
64                         return VisitorForUnderlyingVariable<V, E>.IsUnderlyingVariable (expr, this);
65                 }
66
67                 public bool IsNull (E expr)
68                 {
69                         return VisitorForIsNull<V, E>.IsNull (expr, this);
70                 }
71
72                 public bool IsConstant (E expr, out object value, out TypeNode type)
73                 {
74                         return VisitorForValueOf<V, E>.IsConstant (expr, out value, out type, this);
75                 }
76
77                 public bool IsSizeof (E expr, out TypeNode type)
78                 {
79                         return VisitorForSizeOf<V, E>.IsSizeOf (expr, out type, this);
80                 }
81
82                 public bool IsIsinst (E expr, out E arg, out TypeNode type)
83                 {
84                         return VisitorForIsInst<V, E>.IsIsInst (expr, out type, out arg, this);
85                 }
86
87                 public bool IsUnaryExpression (E expr, out UnaryOperator op, out E arg)
88                 {
89                         return VisitorForIsUnaryExpression<V, E>.IsUnary (expr, out op, out arg, this);
90                 }
91
92                 public bool IsBinaryExpression (E expr, out BinaryOperator op, out E left, out E right)
93                 {
94                         return VisitorForIsBinaryExpression<V, E>.IsBinary (expr, out op, out left, out right, this);
95                 }
96
97                 public void AddFreeVariables (E expr, ISet<E> set)
98                 {
99                         VisitorForVariablesIn<V, E>.AddFreeVariables (expr, set, this);
100                 }
101
102                 public LispList<PathElement> GetVariableAccessPath (E expr)
103                 {
104                         return ContextProvider.ValueContext.AccessPathList (ContextProvider.ExpressionContext.GetPC (expr), ContextProvider.ExpressionContext.Unrefine (expr), true, false);
105                 }
106
107                 public bool TryGetType (E expr, out TypeNode type)
108                 {
109                         FlatDomain<TypeNode> aType = ContextProvider.ExpressionContext.GetType (expr);
110                         if (aType.IsNormal) {
111                                 type = aType.Concrete;
112                                 return true;
113                         }
114
115                         type = null;
116                         return false;
117                 }
118
119                 public bool TrySizeOfAsConstant (E expr, out int sizeAsConstant)
120                 {
121                         return TrySizeOf (expr, out sizeAsConstant);
122                 }
123
124                 private bool TrySizeOf (E expr, out int sizeAsConstant)
125                 {
126                         TypeNode type;
127                         if (VisitorForSizeOf<V, E>.IsSizeOf (expr, out type, this)) {
128                                 int size = this.meta_data_provider.TypeSize (type);
129                                 if (size != -1) {
130                                         sizeAsConstant = size;
131                                         return true;
132                                 }
133                         }
134
135                         sizeAsConstant = -1;
136                         return false;
137                 }
138                 #endregion
139
140                 public FullExpressionDecoder (IMetaDataProvider metaDataProvider, IExpressionContextProvider<E, V> contextProvider)
141                 {
142                         ContextProvider = contextProvider;
143                         this.meta_data_provider = metaDataProvider;
144                         this.VariableVisitor = new VisitorForVariable<V, E> ();
145                         this.UnderlyingVariableVisitor = new VisitorForUnderlyingVariable<V, E> ();
146                         this.UnaryExpressionVisitor = new VisitorForIsUnaryExpression<V, E> ();
147                         this.BinaryExpressionVisitor = new VisitorForIsBinaryExpression<V, E> ();
148                         this.VariablesInVisitor = new VisitorForVariablesIn<V, E> (contextProvider);
149                         this.ValueOfVisitor = new VisitorForValueOf<V, E> ();
150                         this.SizeOfVisitor = new VisitorForSizeOf<V, E> ();
151                         this.IsInstVisitor = new VisitorForIsInst<V, E> ();
152                         this.IsNullVisitor = new VisitorForIsNull<V, E> ();
153                 }
154
155                 public IExpressionContextProvider<E, V> ContextProvider { get; private set; }
156         }
157 }