Beispiel #1
0
        /// <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);
            }
        }
Beispiel #2
0
        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));
        }
Beispiel #3
0
        /// <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();
        }
Beispiel #4
0
        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();
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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));
        }
Beispiel #7
0
        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));
        }
Beispiel #8
0
        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));
        }
Beispiel #9
0
        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));
        }
Beispiel #10
0
        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));
        }
Beispiel #11
0
        /// <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();
            }
        }
Beispiel #12
0
        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));
        }
Beispiel #13
0
        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);
        }
Beispiel #14
0
        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();
        }
Beispiel #16
0
        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));
        }
Beispiel #17
0
        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));
        }
Beispiel #18
0
        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));
        }
Beispiel #19
0
        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));
        }
Beispiel #20
0
        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));
        }
Beispiel #21
0
        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();
        }
Beispiel #22
0
        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));
        }
Beispiel #23
0
        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));
        }
Beispiel #24
0
        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();
        }
Beispiel #28
0
        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();
        }
Beispiel #29
0
        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();
        }
Beispiel #30
0
        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();
        }