1 //
2 // BasicMethodDriver.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 Mono.CodeContracts.Static.AST;
31 using Mono.CodeContracts.Static.Analysis.StackAnalysis;
32 using Mono.CodeContracts.Static.ControlFlow;
33 using Mono.CodeContracts.Static.DataStructures;
34 
35 namespace Mono.CodeContracts.Static.Analysis.Drivers {
36 	class BasicMethodDriver {
37 		private readonly Method method;
38 		private readonly IBasicAnalysisDriver parent;
39 		private ICFG contract_free_cfg;
40 
41 		private ICodeLayer<Dummy, Dummy, IMethodContextProvider, Dummy> contract_free_raw_layer;
42 		private ICodeLayer<int, int, IStackContextProvider, Dummy> contract_free_stack_layer;
43 
BasicMethodDriver(Method method, IBasicAnalysisDriver parent)44 		public BasicMethodDriver (Method method, IBasicAnalysisDriver parent)
45 		{
46 			this.method = method;
47 			this.parent = parent;
48 
49 			RawLayer = CodeLayerFactory.Create (
50 			                                    this.parent.SubroutineFacade.GetControlFlowGraph (method).GetDecoder (parent.MetaDataProvider),
51 			                                    parent.MetaDataProvider,
52 			                                    parent.ContractProvider, dummy => "", dummy => "");
53 
54 			if (DebugOptions.Debug) {
55 				Console.WriteLine ("-----APC based CFG-----");
56 				RawLayer.ILDecoder.ContextProvider.MethodContext.CFG.Print (Console.Out, RawLayer.Printer, null, null);
57 			}
58 
59 			StackLayer = CodeLayerFactory.Create (
60 			                                      StackDepthFactory.Create (RawLayer.ILDecoder, RawLayer.MetaDataProvider),
61 			                                      RawLayer.MetaDataProvider,
62 			                                      RawLayer.ContractProvider, (i => "s" + i.ToString ()), i => "s" + i.ToString ()
63 				);
64 
65 			if (DebugOptions.Debug)
66 			{
67 				Console.WriteLine ("-----Stack based CFG-----");
68 				StackLayer.ILDecoder.ContextProvider.MethodContext.CFG.Print (Console.Out, StackLayer.Printer, null, null);
69 			}
70 		}
71 
72 		public Method CurrentMethod
73 		{
74 			get { return this.method; }
75 		}
76 
77 		public IBasicAnalysisDriver AnalysisDriver
78 		{
79 			get { return this.parent; }
80 		}
81 
82 		public ICodeLayer<Dummy, Dummy, IMethodContextProvider, Dummy> RawLayer { get; private set; }
83 		public ICodeLayer<int, int, IStackContextProvider, Dummy> StackLayer { get; private set; }
84 
85 		public ICodeLayer<Dummy, Dummy, IMethodContextProvider, Dummy> ContractFreeRawLayer
86 		{
87 			get
88 			{
89 				if (this.contract_free_raw_layer == null) {
90 					this.contract_free_raw_layer =
91 						CodeLayerFactory.Create (ContractFreeCFG.GetDecoder (this.parent.MetaDataProvider),
92 						                         RawLayer.MetaDataProvider,
93 						                         RawLayer.ContractProvider,
94 						                         RawLayer.ExpressionToString, RawLayer.VariableToString, RawLayer.Printer);
95 				}
96 				return this.contract_free_raw_layer;
97 			}
98 		}
99 
100 		public ICodeLayer<int, int, IStackContextProvider, Dummy> ContractFreeStackLayer
101 		{
102 			get
103 			{
104 				if (this.contract_free_stack_layer == null) {
105 					this.contract_free_stack_layer =
106 						CodeLayerFactory.Create (StackDepthFactory.Create (ContractFreeRawLayer.ILDecoder, this.contract_free_raw_layer.MetaDataProvider),
107 						                         ContractFreeRawLayer.MetaDataProvider,
108 						                         ContractFreeRawLayer.ContractProvider,
109 						                         StackLayer.ExpressionToString, StackLayer.VariableToString, StackLayer.Printer);
110 				}
111 				return this.contract_free_stack_layer;
112 			}
113 		}
114 
115 		public ICFG ContractFreeCFG
116 		{
117 			get
118 			{
119 				if (this.contract_free_cfg == null) {
120 					this.contract_free_cfg = new ContractFilteredCFG (RawLayer.ILDecoder.ContextProvider.MethodContext.CFG);
121 
122 					if (DebugOptions.Debug)
123 					{
124 						Console.WriteLine ("------raw contract-free cfg -----------------");
125 						this.contract_free_cfg.Print (Console.Out, RawLayer.Printer, null, null);
126 					}
127 				}
128 				return this.contract_free_cfg;
129 			}
130 		}
131 
132 		public ICFG CFG
133 		{
134 			get { return StackLayer.ILDecoder.ContextProvider.MethodContext.CFG; }
135 		}
136 	}
137 }
138