2 using Mono.CodeContracts.Static.AST;
3 using Mono.CodeContracts.Static.Analysis.ExpressionAnalysis;
4 using Mono.CodeContracts.Static.Analysis.ExpressionAnalysis.Decoding;
5 using Mono.CodeContracts.Static.Analysis.HeapAnalysis;
6 using Mono.CodeContracts.Static.ControlFlow;
7 using Mono.CodeContracts.Static.DataStructures;
8 using Mono.CodeContracts.Static.Providers;
9 using Mono.CodeContracts.Static.Proving;
11 namespace Mono.CodeContracts.Static.Analysis.Drivers {
12 class CodeContractsAnalysisDriver<MethodResult>
13 : AnalysisDriver<LabeledSymbol<APC, SymbolicValue>, SymbolicValue> {
14 public CodeContractsAnalysisDriver (IBasicAnalysisDriver basicDriver)
19 public override IMethodDriver<LabeledSymbol<APC, SymbolicValue>, SymbolicValue> CreateMethodDriver (Method method)
21 return new MethodDriver (method, this);
24 #region Nested type: MethodDriver
25 private class MethodDriver : BasicMethodDriver,
26 IMethodDriver<LabeledSymbol<APC, SymbolicValue>, SymbolicValue>,
27 IFactBase<SymbolicValue> {
28 private Func<LabeledSymbol<APC, SymbolicValue>, string> expr2String;
29 private IFullExpressionDecoder<SymbolicValue, LabeledSymbol<APC, SymbolicValue>> expression_decoder;
30 private HeapAnalysis.HeapAnalysis heap_analysis;
32 public MethodDriver (Method method,
33 CodeContractsAnalysisDriver<MethodResult> parent)
34 : base (method, parent)
38 private new AnalysisDriver<LabeledSymbol<APC, SymbolicValue>, SymbolicValue> AnalysisDriver
40 get { return (AnalysisDriver<LabeledSymbol<APC, SymbolicValue>, SymbolicValue>) base.AnalysisDriver; }
43 #region IFactBase<SymbolicValue> Members
44 public ProofOutcome IsNull (APC pc, SymbolicValue variable)
46 return ProofOutcome.Top;
49 public ProofOutcome IsNonNull (APC pc, SymbolicValue variable)
51 return ProofOutcome.Top;
54 public bool IsUnreachable (APC pc)
56 return this.heap_analysis.IsUnreachable (pc);
60 #region IMethodDriver<LabeledSymbol<APC,SymbolicValue>,SymbolicValue> Members
61 public ICodeLayer<SymbolicValue, SymbolicValue,
62 IValueContextProvider<SymbolicValue>,
63 IImmutableMap<SymbolicValue, LispList<SymbolicValue>>> ValueLayer { get; private set; }
65 public ICodeLayer<LabeledSymbol<APC, SymbolicValue>, SymbolicValue,
66 IExpressionContextProvider<LabeledSymbol<APC, SymbolicValue>, SymbolicValue>,
67 IImmutableMap<SymbolicValue, LispList<SymbolicValue>>> ExpressionLayer { get; private set; }
69 public ICodeLayer<SymbolicValue, SymbolicValue,
70 IValueContextProvider<SymbolicValue>,
71 IImmutableMap<SymbolicValue, LispList<SymbolicValue>>> HybridLayer { get; private set; }
73 public IExpressionContextProvider<LabeledSymbol<APC, SymbolicValue>, SymbolicValue> ContextProvider
75 get { return ExpressionLayer.ILDecoder.ContextProvider; }
78 public IMetaDataProvider MetaDataProvider
80 get { return RawLayer.MetaDataProvider; }
83 public IFactBase<SymbolicValue> BasicFacts
88 public IFullExpressionDecoder<SymbolicValue, LabeledSymbol<APC, SymbolicValue>> ExpressionDecoder
92 if (this.expression_decoder == null)
93 this.expression_decoder =
94 new FullExpressionDecoder<SymbolicValue, LabeledSymbol<APC, SymbolicValue>>(MetaDataProvider, ContextProvider);
95 return this.expression_decoder;
99 public void RunHeapAndExpressionAnalyses ()
101 if (this.heap_analysis != null)
104 this.heap_analysis = new HeapAnalysis.HeapAnalysis (StackLayer);
105 StackLayer.CreateForward (this.heap_analysis) (this.heap_analysis.InitialValue ());
107 ValueLayer = CodeLayerFactory.Create (
108 this.heap_analysis.GetDecoder (StackLayer.ILDecoder), StackLayer.MetaDataProvider, StackLayer.ContractProvider,
109 source => source.ToString (), dest => dest.ToString ());
110 var expressionAnalysis = new ExpressionAnalysisFacade<SymbolicValue, IValueContextProvider<SymbolicValue>, IImmutableMap<SymbolicValue, LispList<SymbolicValue>>>
111 (ValueLayer, this.heap_analysis.IsUnreachable);
112 ValueLayer.CreateForward (expressionAnalysis.CreateExpressionAnalysis ()) (expressionAnalysis.InitialValue (SymbolicValue.GetUniqueKey));
114 if (DebugOptions.Debug)
116 Console.WriteLine ("------------Value based CFG-----------------");
117 ValueLayer.ILDecoder.ContextProvider.MethodContext.CFG.Print (Console.Out, ValueLayer.Printer, null, null);
121 <APC, LabeledSymbol<APC, SymbolicValue>, SymbolicValue, IExpressionContextProvider<LabeledSymbol<APC, SymbolicValue>, SymbolicValue>, IImmutableMap<SymbolicValue, LispList<SymbolicValue>>>
122 decoder = expressionAnalysis.GetDecoder (ValueLayer.ILDecoder);
123 this.expr2String = ExpressionPrinterFactory.Printer (decoder.ContextProvider, this);
124 ExpressionLayer = CodeLayerFactory.Create (decoder, ValueLayer.MetaDataProvider, ValueLayer.ContractProvider,
125 this.expr2String, ValueLayer.VariableToString);
127 if (DebugOptions.Debug)
129 Console.WriteLine ("------------Expression based CFG-------------");
130 ExpressionLayer.ILDecoder.ContextProvider.MethodContext.CFG.Print (Console.Out, ExpressionLayer.Printer, null, null);
133 HybridLayer = CodeLayerFactory.Create (ValueLayer.ILDecoder, ValueLayer.MetaDataProvider, ValueLayer.ContractProvider,
134 ValueLayer.ExpressionToString,
135 ValueLayer.VariableToString, ExpressionLayer.Printer);
138 public int KeyConverter (SymbolicValue var)
140 return SymbolicValue.GetUniqueKey (var);