/// <summary> /// Translates the specified text from P# to C#. /// </summary> /// <param name="text">Text</param> /// <returns>Text</returns> public static string Translate(string text, out string errors) { var configuration = Configuration.Create(); configuration.Verbose = 2; errors = null; var context = CompilationContext.Create(configuration).LoadSolution(text); try { ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree(); return(syntaxTree.ToString()); } catch (ParsingException ex) { errors = ex.Message; return(null); } catch (RewritingException ex) { errors = ex.Message; return(null); } }
public void TestNamespaceDeclarationCompact() { var test = @" namespace Foo{}"; var configuration = Configuration.Create(); configuration.Verbose = 2; var context = CompilationContext.Create(configuration).LoadSolution(test); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree(); var expected = @" using Microsoft.PSharp; namespace Foo { }"; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), syntaxTree.ToString().Replace("\n", string.Empty)); }
/// <summary> /// Starts the P# parsing process. /// </summary> public void Start() { Output.WriteLine(". Rewriting"); // Creates and runs a P# rewriting engine. RewritingEngine.Create(this.CompilationContext).Run(); }
public void TestAccessAfterSendInCallee() { var test = @" using Microsoft.PSharp; namespace Foo { class eUnit : Event { public int Value; public eUnit(int value) : base() { this.Value = value; } } class M : Machine { MachineId Target; [Start] [OnEntry(nameof(FirstOnEntryAction))] class First : MachineState { } void FirstOnEntryAction() { int value = 0; this.Target = this.CreateMachine(typeof(M)); this.Foo(value); } void Foo(int value) { this.Send(this.Target, new eUnit(value)); value = 1; } } }"; var configuration = base.GetConfiguration(); IO.StartWritingToMemory(); var context = CompilationContext.Create(configuration).LoadSolution(test, "cs"); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); AnalysisErrorReporter.ResetStats(); StaticAnalysisEngine.Create(context).Run(); var stats = AnalysisErrorReporter.GetStats(); var expected = "No static analysis errors detected."; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats); IO.StopWritingToMemory(); }
private CompilationContext CompileTest(Configuration configuration, string test, bool isPSharpProgram) { var context = CompilationContext.Create(configuration).LoadSolution(test, isPSharpProgram ? "psharp" : "cs"); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); return(context); }
public void TestGenericEventDeclarationWithPayload() { var test = @" namespace Foo { event e1<T, K> (m:K, n:T); internal event e2 (m:string); public event e3 (n:int); }"; var configuration = Configuration.Create(); configuration.Verbose = 2; var context = CompilationContext.Create(configuration).LoadSolution(test); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree(); var expected = @" using Microsoft.PSharp; namespace Foo { class e1<T,K> : Event { public K m; public T n; public e1(K m, T n) : base() { this.m = m; this.n = n; } } internal class e2 : Event { public string m; public e2(string m) : base() { this.m = m; } } public class e3 : Event { public int n; public e3(int n) : base() { this.n = n; } } }"; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), syntaxTree.ToString().Replace("\n", string.Empty)); }
public void TestCreateNamedMachineStatement() { var test = @" namespace Foo { event e1; machine M { machine Target; start state S { entry { create(M, ""NamedMachine""); } } } }"; var configuration = Configuration.Create(); configuration.Verbose = 2; var context = CompilationContext.Create(configuration).LoadSolution(test); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree(); var expected = @" using Microsoft.PSharp; namespace Foo { class e1 : Event { public e1() : base() { } } class M : Machine { MachineId Target; [Microsoft.PSharp.Start] [OnEntry(nameof(psharp_S_on_entry_action))] class S : MachineState { } protected void psharp_S_on_entry_action() { this.CreateMachine(typeof(M),""NamedMachine""); } } }"; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), syntaxTree.ToString().Replace("\n", string.Empty)); }
public void TestGotoStateStatementWithPSharpAPI() { var test = @" using Microsoft.PSharp; namespace Foo { class M : Machine { [Microsoft.PSharp.Start] [OnEntry(nameof(psharp_S1_on_entry_action))] class S1 : MachineState { } class S2 : MachineState { } protected void psharp_S1_on_entry_action() { this.Goto(typeof(S2)); } } }"; var configuration = Configuration.Create(); configuration.Verbose = 2; var context = CompilationContext.Create(configuration).LoadSolution(test, "cs"); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].CSharpPrograms[0].GetSyntaxTree(); var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { [Microsoft.PSharp.Start] [OnEntry(nameof(psharp_S1_on_entry_action))] class S1 : MachineState { } class S2 : MachineState { } protected void psharp_S1_on_entry_action() { { this.Goto(typeof(S2));return; } } } }"; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), syntaxTree.ToString().Replace(Environment.NewLine, string.Empty)); }
public void TestMachineOnEventGotoStateDeclaration2() { var test = @" namespace Foo { machine M { group G { start state S1 { on e1 goto S2; on e2 goto S3; } state S2 {} state S3 {} } } }"; var configuration = Configuration.Create(); configuration.Verbose = 2; var context = CompilationContext.Create(configuration).LoadSolution(test); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree(); var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { class G : StateGroup { [Microsoft.PSharp.Start] [OnEventGotoState(typeof(e1), typeof(S2))] [OnEventGotoState(typeof(e2), typeof(S3))] public class S1 : MachineState { } public class S2 : MachineState { } public class S3 : MachineState { } } } }"; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty).Replace("\n", string.Empty), syntaxTree.ToString().Replace("\n", string.Empty)); }
public void TestMachineMultipleGroups() { var test = @" namespace Foo { machine M { group G1 { start state S1 { entry { jump(S1); } } } group G2 { state S1 { entry { jump(S1); } } } } }"; var configuration = Configuration.Create(); configuration.Verbose = 2; var context = CompilationContext.Create(configuration).LoadSolution(test); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree(); var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { class G1 : StateGroup { [Microsoft.PSharp.Start] [OnEntry(nameof(psharp_G1_S1_on_entry_action))] public class S1 : MachineState { } } class G2 : StateGroup { [OnEntry(nameof(psharp_G2_S1_on_entry_action))] public class S1 : MachineState { } } protected void psharp_G1_S1_on_entry_action(){ { this.Goto(typeof(G1.S1));return; } } protected void psharp_G2_S1_on_entry_action(){ { this.Goto(typeof(G2.S1));return; } } } }"; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty).Replace("\n", string.Empty), syntaxTree.ToString().Replace("\n", string.Empty)); }
/// <summary> /// Starts the P# parsing process. /// </summary> public void Start() { Output.PrintLine(". Rewriting"); foreach (var target in this.CompilationContext.Configuration.CompilationTargets) { this.CompilationContext.ActiveCompilationTarget = target; // Creates and runs a P# rewriting engine. RewritingEngine.Create(this.CompilationContext).Run(); } }
public void TestOMultipleGenericEventGotoStateDeclarationWithBody() { var test = @" namespace Foo { machine M { start state S1 { on e goto S2 with {} on e<int> goto S2 with {} on e<List<Tuple<bool, object>>, Dictionary<string, float>> goto S2 with {} } } }"; var configuration = Configuration.Create(); configuration.Verbose = 2; var context = CompilationContext.Create(configuration).LoadSolution(test); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree(); var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { [Microsoft.PSharp.Start] [OnEventGotoState(typeof(e), typeof(S2), nameof(psharp_S1_e_action))] [OnEventGotoState(typeof(e<int>), typeof(S2), nameof(psharp_S1_e_type_1_action))] [OnEventGotoState(typeof(e<List<Tuple<bool,object>>,Dictionary<string,float>>), typeof(S2), nameof(psharp_S1_e_type_2_action))] class S1 : MachineState { } protected void psharp_S1_e_action() { } protected void psharp_S1_e_type_1_action() { } protected void psharp_S1_e_type_2_action() { } } }"; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), syntaxTree.ToString().Replace("\n", string.Empty)); }
internal static CompilationContext RunRewriter(string test, bool isPSharpProgram = true) { var configuration = Configuration.Create(); configuration.Verbose = 2; // There is some inconsistency around whether the rewriting process strips leading newlines, so make sure there are none. var context = CompilationContext.Create(configuration).LoadSolution(test.Trim(), isPSharpProgram ? "psharp" : "cs"); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); return(context); }
public void TestMachineEntryAndExitDeclaration() { var test = @" namespace Foo { machine M { group G { start state S { entry {} exit {} } } } }"; var configuration = Configuration.Create(); configuration.Verbose = 2; var context = CompilationContext.Create(configuration).LoadSolution(test); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree(); var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { class G : StateGroup { [Microsoft.PSharp.Start] [OnEntry(nameof(psharp_G_S_on_entry_action))] [OnExit(nameof(psharp_G_S_on_exit_action))] public class S : MachineState { } } protected void psharp_G_S_on_entry_action(){} protected void psharp_G_S_on_exit_action(){} } }"; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty).Replace("\n", string.Empty), syntaxTree.ToString().Replace("\n", string.Empty)); }
public void TestPublicFieldVisibility() { var test = @" using Microsoft.PSharp; namespace Foo { class M : Machine { public int Num; [Start] [OnEntry(nameof(FirstOnEntryAction))] class First : MachineState { } void FirstOnEntryAction() { this.Num = 1; } } }"; var configuration = base.GetConfiguration(); IO.StartWritingToMemory(); var context = CompilationContext.Create(configuration).LoadSolution(test, "cs"); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); ErrorReporter.ShowWarnings = true; AnalysisErrorReporter.ResetStats(); StaticAnalysisEngine.Create(context).Run(); var stats = AnalysisErrorReporter.GetStats(); var expected = "Static analysis detected '0' errors and '1' warning."; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats); Console.WriteLine(IO.GetOutput()); var error = "Warning: Field 'int Num' of machine 'Foo.M' is declared as " + "'public'. at 'public int Num;' in Program.cs:line 7"; Assert.AreEqual(error.Replace(Environment.NewLine, string.Empty), IO.GetOutput().Replace(Environment.NewLine, string.Empty)); IO.StopWritingToMemory(); }
public void TestSimpleGenericEventDeclaration() { var test = @" namespace Foo { event e1<T>; internal event e2; public event e3; }"; var configuration = Configuration.Create(); configuration.Verbose = 2; var context = CompilationContext.Create(configuration).LoadSolution(test); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree(); var expected = @" using Microsoft.PSharp; namespace Foo { class e1<T> : Event { public e1() : base() { } } internal class e2 : Event { public e2() : base() { } } public class e3 : Event { public e3() : base() { } } }"; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), syntaxTree.ToString().Replace("\n", string.Empty)); }
public void TestMachineOnSimpleGenericEventDoActionDeclarationWithBody() { var test = @" namespace Foo { machine M { group G { start state S1 { on e<int> do {} } } } }"; var configuration = Configuration.Create(); configuration.Verbose = 2; var context = CompilationContext.Create(configuration).LoadSolution(test); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree(); var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { class G : StateGroup { [Microsoft.PSharp.Start] [OnEventDoAction(typeof(e<int>), nameof(psharp_G_S1_e_type_0_action))] public class S1 : MachineState { } } protected void psharp_G_S1_e_type_0_action(){} } }"; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty).Replace("\n", string.Empty), syntaxTree.ToString().Replace("\n", string.Empty)); }
public void TestMonitorOnEventDoActionDeclaration() { var test = @" namespace Foo { monitor M { group G { start state S1 { on e do Bar; } } } }"; var configuration = Configuration.Create(); configuration.Verbose = 2; var context = CompilationContext.Create(configuration).LoadSolution(test); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree(); var expected = @" using Microsoft.PSharp; namespace Foo { class M : Monitor { class G : StateGroup { [Microsoft.PSharp.Start] [OnEventDoAction(typeof(e), nameof(Bar))] public class S1 : MonitorState { } } } }"; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty).Replace("\n", string.Empty), syntaxTree.ToString().Replace("\n", string.Empty)); }
public void TestWildcardEventAction() { var test = @" namespace Foo { machine M { start state S { on *,e1.e2 goto S2; on * push S2; } } }"; var configuration = Configuration.Create(); configuration.Verbose = 2; var context = CompilationContext.Create(configuration).LoadSolution(test); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree(); var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { [Microsoft.PSharp.Start] [OnEventGotoState(typeof(Microsoft.PSharp.WildCardEvent), typeof(S2))] [OnEventGotoState(typeof(e1.e2), typeof(S2))] [OnEventPushState(typeof(Microsoft.PSharp.WildCardEvent), typeof(S2))] class S : MachineState { } } }"; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), syntaxTree.ToString().Replace("\n", string.Empty)); }
public void TestOnComplexGenericEventDoActionDeclaration() { var test = @" using System.Collection.Generic; namespace Foo { machine M { start state S1 { on e<List<Tuple<bool, object>>, Dictionary<string, float>> do Bar; } } }"; var configuration = Configuration.Create(); configuration.Verbose = 2; var context = CompilationContext.Create(configuration).LoadSolution(test); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree(); var expected = @" using Microsoft.PSharp; using System.Collection.Generic; namespace Foo { class M : Machine { [Microsoft.PSharp.Start] [OnEventDoAction(typeof(e<List<Tuple<bool,object>>,Dictionary<string,float>>), nameof(Bar))] class S1 : MachineState { } } }"; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), syntaxTree.ToString().Replace("\n", string.Empty)); }
public void TestBasicLoop() { var test = @" using Microsoft.PSharp; namespace Foo { class M : Machine { [Start] [OnEntry(nameof(FirstOnEntryAction))] class First : MachineState { } void FirstOnEntryAction() { int k = 10; for (int i = 0; i < k; i++) { k = 2; } k = 3; } } }"; var configuration = base.GetConfiguration(); IO.StartWritingToMemory(); var context = CompilationContext.Create(configuration).LoadSolution(test, "cs"); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); AnalysisErrorReporter.ResetStats(); StaticAnalysisEngine.Create(context).Run(); var stats = AnalysisErrorReporter.GetStats(); var expected = "No static analysis errors detected."; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats); IO.StopWritingToMemory(); }
public void TestIgnoreEventDeclaration() { var test = @" namespace Foo { machine M { start state S { ignore e; } } }"; var configuration = Configuration.Create(); configuration.Verbose = 2; var context = CompilationContext.Create(configuration).LoadSolution(test); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree(); var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { [Microsoft.PSharp.Start] [IgnoreEvents(typeof(e))] class S : MachineState { } } }"; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), syntaxTree.ToString().Replace("\n", string.Empty)); }
public void TestDeferEventDeclarationQualifiedComplex() { var test = @" namespace Foo { machine M { start state S { defer e1<int>, halt, default, Foo.e2<Bar.e3>; } } }"; var configuration = Configuration.Create(); configuration.Verbose = 2; var context = CompilationContext.Create(configuration).LoadSolution(test); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree(); var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { [Microsoft.PSharp.Start] [DeferEvents(typeof(e1<int>), typeof(Microsoft.PSharp.Halt), typeof(Microsoft.PSharp.Default), typeof(Foo.e2<Bar.e3>))] class S : MachineState { } } }"; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), syntaxTree.ToString().Replace("\n", string.Empty)); }
public void TestMemberVisibility() { var test = @" namespace Foo { class M : Machine { int Num; [Start] [OnEntry(nameof(FirstOnEntryAction))] class First : MachineState { } void FirstOnEntryAction() { this.Num = 1; } } }"; var configuration = base.GetConfiguration(); IO.StartWritingToMemory(); var context = CompilationContext.Create(configuration).LoadSolution(test, "cs"); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); AnalysisErrorReporter.ResetStats(); StaticAnalysisEngine.Create(context).Run(); var stats = AnalysisErrorReporter.GetStats(); var expected = "No static analysis errors detected."; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats); IO.StopWritingToMemory(); }
public void TestWriteAccessAfterSendInCallee5Fail() { var test = @" using Microsoft.PSharp; namespace Foo { class eUnit : Event { public Letter Letter; public eUnit(Letter letter) : base() { this.Letter = letter; } } struct Letter { public string Text; public int Num; public Letter(string text, int num) { this.Text = text; this.Num = num; } public int Get() { return 0; } } class M : Machine { MachineId Target; Letter Letter; [Start] [OnEntry(nameof(FirstOnEntryAction))] class First : MachineState { } void FirstOnEntryAction() { var letter = new Letter(""test"", 0); this.Target = this.CreateMachine(typeof(M)); this.Send(this.Target, new eUnit(letter)); this.Foo(letter); } void Foo(Letter letter) { var k = letter.Get(); // ERROR } } }"; var configuration = base.GetConfiguration(); IO.StartWritingToMemory(); var context = CompilationContext.Create(configuration).LoadSolution(test, "cs"); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); AnalysisErrorReporter.ResetStats(); StaticAnalysisEngine.Create(context).Run(); var stats = AnalysisErrorReporter.GetStats(); var expected = "Static analysis detected '1' error."; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats); var error = "Error: Method 'FirstOnEntryAction' of machine 'Foo.M' " + "accesses 'letter' after giving up its ownership."; var actual = IO.GetOutput(); Assert.AreEqual(error.Replace(Environment.NewLine, string.Empty), actual.Substring(0, actual.IndexOf(Environment.NewLine))); IO.StopWritingToMemory(); }
public void TestWriteAccessAfterSendInCallee3Fail() { var test = @" using Microsoft.PSharp; namespace Foo { class eUnit : Event { public Letter Letter; public eUnit(Letter letter) : base() { this.Letter = letter; } } struct Letter { public string Text; public int Num; public Letter(string text, int num) { this.Text = text; this.Num = num; } } class M : Machine { MachineId Target; Letter Letter; [Start] [OnEntry(nameof(FirstOnEntryAction))] class First : MachineState { } void FirstOnEntryAction() { var letter = new Letter(""test"", 0); this.Target = this.CreateMachine(typeof(M)); this.Send(this.Target, new eUnit(letter)); this.Foo(letter); } void Foo(Letter letter) { this.Letter = letter; // ERROR letter = new Letter(""test2"", 2); this.Letter.Num = 1; // ERROR int num = this.Letter.Num; // ERROR letter.Text = ""Bangalore""; this.Letter.Text = ""Taipei""; // ERROR } } }"; var configuration = base.GetConfiguration(); configuration.DoStateTransitionAnalysis = false; IO.StartWritingToMemory(); var context = CompilationContext.Create(configuration).LoadSolution(test, "cs"); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); AnalysisErrorReporter.ResetStats(); StaticAnalysisEngine.Create(context).Run(); var stats = AnalysisErrorReporter.GetStats(); var expected = "Static analysis detected '7' errors."; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats); IO.StopWritingToMemory(); }
public void TestReturnAliasAccess8Fail() { var test = @" using Microsoft.PSharp; namespace Foo { class eUnit : Event { public Envelope Envelope; public eUnit(Envelope envelope) : base() { this.Envelope = envelope; } } struct Envelope { public Letter Letter; public Envelope(Letter letter) { this.Letter = letter; } } struct Letter { public string Text; public int Num; public Letter(string text, int num) { this.Text = text; this.Num = num; } } class M : Machine { MachineId Target; Letter Letter; [Start] [OnEntry(nameof(FirstOnEntryAction))] class First : MachineState { } void FirstOnEntryAction() { this.Target = this.CreateMachine(typeof(M)); this.Foo(); } void Foo() { var letter = new Letter(""test"", 0); var envelope = new Envelope(letter); envelope.Letter = this.Bar(); this.Send(this.Target, new eUnit(envelope)); } Letter Bar() { return this.Letter; } } }"; var configuration = base.GetConfiguration(); configuration.DoStateTransitionAnalysis = false; IO.StartWritingToMemory(); var context = CompilationContext.Create(configuration).LoadSolution(test, "cs"); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); AnalysisErrorReporter.ResetStats(); StaticAnalysisEngine.Create(context).Run(); var stats = AnalysisErrorReporter.GetStats(); var expected = "Static analysis detected '1' error."; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats); var error = "Error: Method 'Foo' of machine 'Foo.M' sends 'envelope', " + "which contains data from field 'Foo.M.Letter'."; var actual = IO.GetOutput(); Assert.AreEqual(error.Replace(Environment.NewLine, string.Empty), actual.Substring(0, actual.IndexOf(Environment.NewLine))); IO.StopWritingToMemory(); }
public void TestAccessInVirtualMethod() { var test = @" using Microsoft.PSharp; namespace Foo { class eUnit : Event { public Letter Letter; public eUnit(Letter letter) : base() { this.Letter = letter; } } struct Letter { public string Text; public Letter(string text) { this.Text = text; } } internal class Envelope { internal Letter Letter; internal virtual void Foo(Letter letter) { } } internal class SuperEnvelope : Envelope { internal override void Foo(Letter letter) { letter.Text = ""Bangalore""; } } class M : Machine { MachineId Target; [Start] [OnEntry(nameof(FirstOnEntryAction))] class First : MachineState { } void FirstOnEntryAction() { var letter = new Letter(""London""); this.Target = this.CreateMachine(typeof(M)); Envelope envelope = new Envelope(); this.Send(this.Target, new eUnit(letter)); envelope.Foo(letter); } } }"; var configuration = base.GetConfiguration(); IO.StartWritingToMemory(); var context = CompilationContext.Create(configuration).LoadSolution(test, "cs"); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); AnalysisErrorReporter.ResetStats(); StaticAnalysisEngine.Create(context).Run(); var stats = AnalysisErrorReporter.GetStats(); var expected = "No static analysis errors detected."; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats); IO.StopWritingToMemory(); }
public void TestComplexAccessesInCall11Fail() { var test = @" using Microsoft.PSharp; namespace Foo { class eUnit : Event { public Letter Letter; public eUnit(Letter letter) : base() { this.Letter = letter; } } struct Letter { public string Text; public Letter(string text) { this.Text = text; } } class OtherClass { AnotherClass AC; public void Foo(Letter letter) { var ac = new AnotherClass(letter); this.AC = ac; this.AC.Bar(); } } class AnotherClass { internal Letter Letter; public AnotherClass(Letter letter) { this.Letter = letter; } public void Bar() { this.Letter.Text = ""Test""; // ERROR } } class M : Machine { MachineId Target; Letter Letter; [Start] [OnEntry(nameof(FirstOnEntryAction))] class First : MachineState { } void FirstOnEntryAction() { this.Target = this.CreateMachine(typeof(M)); Letter letter = new Letter(""London""); var oc = new OtherClass(); this.Send(this.Target, new eUnit(letter)); oc.Foo(letter); } } }"; var configuration = base.GetConfiguration(); configuration.DoStateTransitionAnalysis = false; IO.StartWritingToMemory(); var context = CompilationContext.Create(configuration).LoadSolution(test, "cs"); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); AnalysisErrorReporter.ResetStats(); StaticAnalysisEngine.Create(context).Run(); var stats = AnalysisErrorReporter.GetStats(); var expected = "Static analysis detected '2' errors."; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats); IO.StopWritingToMemory(); }
public void TestFieldSendAlias6Fail() { var test = @" using Microsoft.PSharp; namespace Foo { class eUnit : Event { public Letter Letter; public eUnit(Letter letter) : base() { this.Letter = letter; } } struct Letter { public string Text; public int Num; public Letter(string text, int num) { this.Text = text; this.Num = num; } } class M : Machine { MachineId Target; Object Obj; [Start] [OnEntry(nameof(FirstOnEntryAction))] class First : MachineState { } void FirstOnEntryAction() { this.Target = this.CreateMachine(typeof(M)); this.Obj = (this.ReceivedEvent as eUnit).Letter; this.Send(this.Target, new eUnit((this.ReceivedEvent as eUnit).Letter)); } } }"; var configuration = base.GetConfiguration(); configuration.DoStateTransitionAnalysis = false; IO.StartWritingToMemory(); var context = CompilationContext.Create(configuration).LoadSolution(test, "cs"); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); AnalysisErrorReporter.ResetStats(); StaticAnalysisEngine.Create(context).Run(); var stats = AnalysisErrorReporter.GetStats(); var expected = "Static analysis detected '1' error."; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats); var error = "Error: Method 'FirstOnEntryAction' of machine 'Foo.M' sends " + "'ReceivedEvent', which contains data from field 'Foo.M.Obj'."; var actual = IO.GetOutput(); Assert.AreEqual(error.Replace(Environment.NewLine, string.Empty), actual.Substring(0, actual.IndexOf(Environment.NewLine))); IO.StopWritingToMemory(); }