Esempio n. 1
0
            public SyntaxNode MkClass()
            {
                var generator = translator.generator;
                //StartState property (getter only, since there's no setter in the base class):
                string startState         = machineInfo.initStateName;
                var    startStateProperty =
                    SyntaxFactory.PropertyDeclaration(
                        SyntaxFactory.IdentifierName("PrtState"),
                        SyntaxFactory.Identifier("StartState"))
                    .WithModifiers(
                        SyntaxFactory.TokenList(
                            new[] {
                    SyntaxFactory.Token(SyntaxKind.PublicKeyword),
                    SyntaxFactory.Token(SyntaxKind.OverrideKeyword)
                }))
                    .WithAccessorList(
                        SyntaxFactory.AccessorList(
                            SyntaxFactory.SingletonList <AccessorDeclarationSyntax>(
                                SyntaxFactory.AccessorDeclaration(
                                    SyntaxKind.GetAccessorDeclaration,
                                    SyntaxFactory.Block(
                                        SyntaxFactory.SingletonList <StatementSyntax>(
                                            SyntaxFactory.ReturnStatement(
                                                SyntaxFactory.IdentifierName(startState))))))))
                    .NormalizeWhitespace();

                machineMembers.Add(startStateProperty);

                //Add getters/setters for machine variables:
                int ind = 0;

                foreach (var pair in machineInfo.localVariableToVarInfo)
                {
                    SyntaxTokenList modifiers = new SyntaxTokenList();
                    modifiers = modifiers.Add(SyntaxFactory.Token(SyntaxKind.PublicKeyword));
                    var getBody = SyntaxFactory.SingletonList <StatementSyntax>(SyntaxFactory.ReturnStatement(
                                                                                    (ExpressionSyntax)CSharpHelper.MkCSharpElementAccessExpression(
                                                                                        SyntaxFactory.IdentifierName("fields"), ind)));
                    var setBody = SyntaxFactory.SingletonList <StatementSyntax>((StatementSyntax)CSharpHelper.MkCSharpSimpleAssignmentExpressionStatement(
                                                                                    (ExpressionSyntax)CSharpHelper.MkCSharpElementAccessExpression(
                                                                                        SyntaxFactory.IdentifierName("fields"), ind),
                                                                                    SyntaxFactory.IdentifierName("value")));
                    AccessorDeclarationSyntax[] accessorList = new AccessorDeclarationSyntax[]
                    { CSharpHelper.MkCSharpAccessor("get", getBody), CSharpHelper.MkCSharpAccessor("set", setBody) };
                    machineMembers.Add(CSharpHelper.MkCSharpPropertyDecl("PrtValue", VarName(pair.Key), modifiers, accessorList));
                    ind += 1;
                }

                var skeletonMethodBody = generator.ReturnStatement(generator.ObjectCreationExpression(generator.IdentifierName(machineName)));
                var skeletonMethodDecl = generator.MethodDeclaration("MakeSkeleton", null,
                                                                     null, generator.IdentifierName(machineInfo.IsReal ? "PrtImplMachine" : "PrtSpecMachine"),
                                                                     Accessibility.Public,
                                                                     DeclarationModifiers.Override,
                                                                     new SyntaxNode[] { skeletonMethodBody });

                machineMembers.Add(skeletonMethodDecl);

                //(this.GetType())
                var returnMethodPars = new SyntaxNode[]
                {
                    generator.InvocationExpression(generator.MemberAccessExpression(generator.ThisExpression(), generator.IdentifierName("GetType")))
                };
                //return app.NextMachineInstanceNumber(this.GetType());
                var nextInstanceNumberMethodBody = generator.ReturnStatement(generator.InvocationExpression(generator.MemberAccessExpression(
                                                                                                                generator.IdentifierName("app"), generator.IdentifierName("NextMachineInstanceNumber")), returnMethodPars));

                //(StateImpl app)
                if (machineInfo.IsReal)
                {
                    var methodPars = new SyntaxNode[] { generator.ParameterDeclaration("app", generator.IdentifierName("StateImpl")) };
                    var nextInstanceNumberMethodDecl = generator.MethodDeclaration("NextInstanceNumber", methodPars,
                                                                                   //null, generator.IdentifierName("int"),
                                                                                   null, generator.TypeExpression(SpecialType.System_Int32),
                                                                                   Accessibility.Public,
                                                                                   DeclarationModifiers.Override,
                                                                                   new SyntaxNode[] { nextInstanceNumberMethodBody });
                    machineMembers.Add(nextInstanceNumberMethodDecl);
                }

                //Name property (getter only):
                var nameProperty =
                    SyntaxFactory.PropertyDeclaration(
                        SyntaxFactory.PredefinedType(
                            SyntaxFactory.Token(SyntaxKind.StringKeyword)),
                        SyntaxFactory.Identifier("Name"))
                    .WithModifiers(
                        SyntaxFactory.TokenList(
                            new[] {
                    SyntaxFactory.Token(SyntaxKind.PublicKeyword),
                    SyntaxFactory.Token(SyntaxKind.OverrideKeyword)
                }))
                    .WithAccessorList(
                        SyntaxFactory.AccessorList(
                            SyntaxFactory.SingletonList <AccessorDeclarationSyntax>(
                                SyntaxFactory.AccessorDeclaration(
                                    SyntaxKind.GetAccessorDeclaration,
                                    SyntaxFactory.Block(
                                        SyntaxFactory.SingletonList <StatementSyntax>(
                                            SyntaxFactory.ReturnStatement(
                                                SyntaxFactory.IdentifierName("\"" + machineName + "\""))))))))
                    .NormalizeWhitespace();

                machineMembers.Add(nameProperty);

                //constructor for cloning
                var constructor_1 = generator.ConstructorDeclaration(machineName, null, Accessibility.Public, baseConstructorArguments: new SyntaxNode[0]);

                machineMembers.Add(constructor_1);

                //Machine class constructor
                //public PONG(StateImpl app, int maxB, bool assume): base (app, maxB, assume)
                List <SyntaxNode> constructorStmtList = new List <SyntaxNode>();

                foreach (var varInfo in machineInfo.localVariableToVarInfo.Values)
                {
                    var defaultValue = CSharpHelper.MkCSharpInvocationExpression(SyntaxFactory.MemberAccessExpression(
                                                                                     SyntaxKind.SimpleMemberAccessExpression,
                                                                                     SyntaxFactory.IdentifierName("PrtValue"),
                                                                                     SyntaxFactory.IdentifierName("PrtMkDefaultValue")), translator.typeContext.PTypeToCSharpExpr(varInfo.type));
                    constructorStmtList.Add(SyntaxFactory.ExpressionStatement(CSharpHelper.MkCSharpInvocationExpression(CSharpHelper.MkCSharpDot("fields", "Add"), defaultValue)));
                }
                if (machineInfo.IsReal)
                {
                    var constructorPars = new SyntaxNode[]
                    {
                        generator.ParameterDeclaration("app", generator.IdentifierName("StateImpl")),
                        generator.ParameterDeclaration("maxB", generator.TypeExpression(SpecialType.System_Int32)),
                        generator.ParameterDeclaration("assume", generator.TypeExpression(SpecialType.System_Boolean))
                    };
                    var baseConstructorArgs = new SyntaxNode[] { generator.IdentifierName("app"), generator.IdentifierName("maxB"), generator.IdentifierName("assume") };

                    var constructor_2 = generator.ConstructorDeclaration(machineName, constructorPars, Accessibility.Public,
                                                                         baseConstructorArguments: baseConstructorArgs,
                                                                         statements: constructorStmtList);
                    machineMembers.Add(constructor_2);
                }
                else
                {
                    var constructorPars = new SyntaxNode[]
                    {
                        generator.ParameterDeclaration("app", generator.IdentifierName("StateImpl"))
                    };
                    var baseConstructorArgs = new SyntaxNode[] { generator.IdentifierName("app") };
                    var constructor_2       = generator.ConstructorDeclaration(machineName, constructorPars, Accessibility.Public,
                                                                               baseConstructorArguments: baseConstructorArgs,
                                                                               statements: constructorStmtList);
                    machineMembers.Add(constructor_2);
                }

                // Fun classes for all functions of the machine:
                foreach (var pair in machineInfo.funNameToFunInfo)
                {
                    MkFunctionDecl funDecl = new MkFunctionDecl(pair.Key, pair.Value, this, translator);
                    funDecl.AddFunClass();
                }

                foreach (var pair in machineInfo.stateNameToStateInfo)
                {
                    string stateName = pair.Key;
                    string stateType = stateName + "_Class";
                    //state instantiation for the machine class constructor:
                    //Example:
                    //PONG_Pong_WaitPing = new PONG_Pong_WaitPing_Class("PONG_Pong_WaitPing", AnonFun1, AnonFun0, false, StateTemperature.Warm);
                    //Consider 6 cases (write a mmethod): for each bool value of hasNullTransition, there are 3 possible "temperatures"
                    mainConstructorFields.Add(MkStateInstantiation(stateName, stateType, pair.Value.entryActionName, pair.Value.exitFunName,
                                                                   pair.Value.hasNullTransition, pair.Value.temperature));
                }

                //State classes for all states of the machine:
                foreach (var pair in machineInfo.stateNameToStateInfo)
                {
                    string stateName = pair.Key;
                    string stateType = stateName + "_Class";
                    //state class declaration:
                    var stateClassDecl =
                        SyntaxFactory.ClassDeclaration(stateType)
                        .WithModifiers(
                            SyntaxFactory.TokenList(
                                SyntaxFactory.Token(SyntaxKind.PublicKeyword)))
                        .WithBaseList(
                            SyntaxFactory.BaseList(
                                SyntaxFactory.SingletonSeparatedList <BaseTypeSyntax>(
                                    SyntaxFactory.SimpleBaseType(
                                        SyntaxFactory.IdentifierName("PrtState")))))
                        .WithMembers(
                            SyntaxFactory.SingletonList <MemberDeclarationSyntax>(
                                SyntaxFactory.ConstructorDeclaration(
                                    SyntaxFactory.Identifier(stateType))
                                .WithModifiers(
                                    SyntaxFactory.TokenList(
                                        SyntaxFactory.Token(SyntaxKind.PublicKeyword)))
                                .WithParameterList(
                                    SyntaxFactory.ParameterList(
                                        SyntaxFactory.SeparatedList <ParameterSyntax>(
                                            new SyntaxNodeOrToken[] {
                        SyntaxFactory.Parameter(
                            SyntaxFactory.Identifier("name"))
                        .WithType(
                            SyntaxFactory.PredefinedType(
                                SyntaxFactory.Token(SyntaxKind.StringKeyword))),
                        SyntaxFactory.Token(SyntaxKind.CommaToken),
                        SyntaxFactory.Parameter(
                            SyntaxFactory.Identifier("entryFun"))
                        .WithType(
                            SyntaxFactory.IdentifierName("PrtFun")),
                        SyntaxFactory.Token(SyntaxKind.CommaToken),
                        SyntaxFactory.Parameter(
                            SyntaxFactory.Identifier("exitFun"))
                        .WithType(
                            SyntaxFactory.IdentifierName("PrtFun")),
                        SyntaxFactory.Token(SyntaxKind.CommaToken),
                        SyntaxFactory.Parameter(
                            SyntaxFactory.Identifier("hasNullTransition"))
                        .WithType(
                            SyntaxFactory.PredefinedType(
                                SyntaxFactory.Token(SyntaxKind.BoolKeyword))),
                        SyntaxFactory.Token(SyntaxKind.CommaToken),
                        SyntaxFactory.Parameter(
                            SyntaxFactory.Identifier("temperature"))
                        .WithType(
                            SyntaxFactory.IdentifierName("StateTemperature"))
                    })))
                                .WithInitializer(
                                    SyntaxFactory.ConstructorInitializer(
                                        SyntaxKind.BaseConstructorInitializer,
                                        SyntaxFactory.ArgumentList(
                                            SyntaxFactory.SeparatedList <ArgumentSyntax>(
                                                new SyntaxNodeOrToken[] {
                        SyntaxFactory.Argument(
                            SyntaxFactory.IdentifierName("name")),
                        SyntaxFactory.Token(SyntaxKind.CommaToken),
                        SyntaxFactory.Argument(
                            SyntaxFactory.IdentifierName("entryFun")),
                        SyntaxFactory.Token(SyntaxKind.CommaToken),
                        SyntaxFactory.Argument(
                            SyntaxFactory.IdentifierName("exitFun")),
                        SyntaxFactory.Token(SyntaxKind.CommaToken),
                        SyntaxFactory.Argument(
                            SyntaxFactory.IdentifierName("hasNullTransition")),
                        SyntaxFactory.Token(SyntaxKind.CommaToken),
                        SyntaxFactory.Argument(
                            SyntaxFactory.IdentifierName("temperature"))
                    }))))
                                .WithBody(
                                    SyntaxFactory.Block())))
                        .NormalizeWhitespace();
                    machineMembers.Add(stateClassDecl);

                    //state declaration:
                    //Example: public static Init Init_State;
                    var stateDeclaration =
                        SyntaxFactory.FieldDeclaration(
                            SyntaxFactory.VariableDeclaration(
                                SyntaxFactory.IdentifierName(stateType))
                            .WithVariables(
                                SyntaxFactory.SingletonSeparatedList <VariableDeclaratorSyntax>(
                                    SyntaxFactory.VariableDeclarator(
                                        SyntaxFactory.Identifier(stateName)))))
                        .WithModifiers(
                            SyntaxFactory.TokenList(
                                new[] {
                        SyntaxFactory.Token(SyntaxKind.PublicKeyword),
                        SyntaxFactory.Token(SyntaxKind.StaticKeyword)
                    }))
                        .NormalizeWhitespace();
                    machineMembers.Add(stateDeclaration);

                    //Add DoDecls to the StateInfo:
                    foreach (var doFun in pair.Value.dos)
                    {
                        ExpressionSyntax doFunExpr = SyntaxFactory.IdentifierName(doFun.Value);
                        if (doFun.Value == "ignore")
                        {
                            doFunExpr = SyntaxFactory.MemberAccessExpression(
                                SyntaxKind.SimpleMemberAccessExpression,
                                SyntaxFactory.IdentifierName("PrtFun"),
                                SyntaxFactory.IdentifierName("IgnoreFun"));
                        }
                        mainConstructorFields.Add(
                            SyntaxFactory.ExpressionStatement(
                                SyntaxFactory.InvocationExpression(
                                    SyntaxFactory.MemberAccessExpression(
                                        SyntaxKind.SimpleMemberAccessExpression,
                                        SyntaxFactory.MemberAccessExpression(
                                            SyntaxKind.SimpleMemberAccessExpression,
                                            SyntaxFactory.IdentifierName(stateName),
                                            SyntaxFactory.IdentifierName("dos")),
                                        SyntaxFactory.IdentifierName("Add")))
                                .WithArgumentList(
                                    SyntaxFactory.ArgumentList(
                                        SyntaxFactory.SeparatedList <ArgumentSyntax>(
                                            new SyntaxNodeOrToken[] {
                            SyntaxFactory.Argument(
                                translator.GetEventVar(doFun.Key)),
                            SyntaxFactory.Token(SyntaxKind.CommaToken),
                            SyntaxFactory.Argument(doFunExpr)
                        }))))
                            .NormalizeWhitespace()
                            );
                    }

                    //Add deferred events (if any) to the state:
                    foreach (var deferredEvent in pair.Value.deferredEvents)
                    {
                        mainConstructorFields.Add(
                            SyntaxFactory.ExpressionStatement(
                                SyntaxFactory.InvocationExpression(
                                    SyntaxFactory.MemberAccessExpression(
                                        SyntaxKind.SimpleMemberAccessExpression,
                                        SyntaxFactory.MemberAccessExpression(
                                            SyntaxKind.SimpleMemberAccessExpression,
                                            SyntaxFactory.IdentifierName(stateName),
                                            SyntaxFactory.IdentifierName("deferredSet")),
                                        SyntaxFactory.IdentifierName("Add")))
                                .WithArgumentList(
                                    SyntaxFactory.ArgumentList(
                                        SyntaxFactory.SingletonSeparatedList <ArgumentSyntax>(
                                            SyntaxFactory.Argument(
                                                translator.GetEventVar(deferredEvent))))))
                            .NormalizeWhitespace()
                            );
                    }

                    //Transition instantiations for the state of the machine:

                    //"transition" + "_" + transition_count
                    foreach (var transition in pair.Value.transitions)
                    {
                        string trigger         = transition.Key;
                        string transition_name = "transition" + "_" + transition_count;
                        if (transition.Value.IsPush)
                        {
                            //push transition:
                            mainConstructorFields.Add(
                                SyntaxFactory.LocalDeclarationStatement(
                                    SyntaxFactory.VariableDeclaration(
                                        SyntaxFactory.IdentifierName("PrtTransition"))
                                    .WithVariables(
                                        SyntaxFactory.SingletonSeparatedList <VariableDeclaratorSyntax>(
                                            SyntaxFactory.VariableDeclarator(
                                                SyntaxFactory.Identifier(transition_name))
                                            .WithInitializer(
                                                SyntaxFactory.EqualsValueClause(
                                                    SyntaxFactory.ObjectCreationExpression(
                                                        SyntaxFactory.IdentifierName("PrtTransition"))
                                                    .WithArgumentList(
                                                        SyntaxFactory.ArgumentList(
                                                            SyntaxFactory.SeparatedList <ArgumentSyntax>(
                                                                new SyntaxNodeOrToken[] {
                                SyntaxFactory.Argument(
                                    SyntaxFactory.MemberAccessExpression(
                                        SyntaxKind.SimpleMemberAccessExpression,
                                        SyntaxFactory.IdentifierName("PrtFun"),
                                        SyntaxFactory.IdentifierName("IgnoreFun"))),
                                SyntaxFactory.Token(SyntaxKind.CommaToken),
                                SyntaxFactory.Argument(
                                    SyntaxFactory.IdentifierName(transition.Value.target)),
                                SyntaxFactory.Token(SyntaxKind.CommaToken),
                                SyntaxFactory.Argument(
                                    SyntaxFactory.LiteralExpression(
                                        SyntaxKind.TrueLiteralExpression))
                            }))))))))
                                .NormalizeWhitespace());
                        }
                        else
                        {
                            //goto transition:
                            mainConstructorFields.Add(
                                SyntaxFactory.LocalDeclarationStatement(
                                    SyntaxFactory.VariableDeclaration(
                                        SyntaxFactory.IdentifierName("PrtTransition"))
                                    .WithVariables(
                                        SyntaxFactory.SingletonSeparatedList <VariableDeclaratorSyntax>(
                                            SyntaxFactory.VariableDeclarator(
                                                SyntaxFactory.Identifier("transition" + "_" + transition_count))
                                            .WithInitializer(
                                                SyntaxFactory.EqualsValueClause(
                                                    SyntaxFactory.ObjectCreationExpression(
                                                        SyntaxFactory.IdentifierName("PrtTransition"))
                                                    .WithArgumentList(
                                                        SyntaxFactory.ArgumentList(
                                                            SyntaxFactory.SeparatedList <ArgumentSyntax>(
                                                                new SyntaxNodeOrToken[] {
                                SyntaxFactory.Argument(
                                    SyntaxFactory.IdentifierName(transition.Value.transFunName)),
                                SyntaxFactory.Token(SyntaxKind.CommaToken),
                                SyntaxFactory.Argument(
                                    SyntaxFactory.IdentifierName(transition.Value.target)),
                                SyntaxFactory.Token(SyntaxKind.CommaToken),
                                SyntaxFactory.Argument(
                                    SyntaxFactory.LiteralExpression(
                                        SyntaxKind.FalseLiteralExpression))
                            }))))))))
                                .NormalizeWhitespace());
                        }
                        //Add transition to the state:
                        mainConstructorFields.Add(
                            SyntaxFactory.ExpressionStatement(
                                SyntaxFactory.InvocationExpression(
                                    SyntaxFactory.MemberAccessExpression(
                                        SyntaxKind.SimpleMemberAccessExpression,
                                        SyntaxFactory.MemberAccessExpression(
                                            SyntaxKind.SimpleMemberAccessExpression,
                                            SyntaxFactory.IdentifierName(stateName),
                                            SyntaxFactory.IdentifierName("transitions")),
                                        SyntaxFactory.IdentifierName("Add")))
                                .WithArgumentList(
                                    SyntaxFactory.ArgumentList(
                                        SyntaxFactory.SeparatedList <ArgumentSyntax>(
                                            new SyntaxNodeOrToken[] {
                            SyntaxFactory.Argument(
                                translator.GetEventVar(trigger)),
                            SyntaxFactory.Token(SyntaxKind.CommaToken),
                            SyntaxFactory.Argument(
                                SyntaxFactory.IdentifierName(transition_name))
                        }))))
                            .NormalizeWhitespace()
                            );
                        transition_count += 1;
                    }
                }

                //Constructor for the machine class:
                //static Machine()
                var mainConstructor =
                    SyntaxFactory.ConstructorDeclaration(
                        SyntaxFactory.Identifier(machineName))
                    .WithModifiers(
                        SyntaxFactory.TokenList(
                            SyntaxFactory.Token(SyntaxKind.StaticKeyword)))
                    .WithBody(
                        SyntaxFactory.Block(mainConstructorFields
                                            ))
                    .NormalizeWhitespace();

                machineMembers.Add(mainConstructor);

                var mainMachineClassDecl = generator.ClassDeclaration(
                    machineName, typeParameters: null,
                    accessibility: Accessibility.Public,
                    baseType: generator.IdentifierName(machineInfo.IsReal ? "PrtImplMachine" : "PrtSpecMachine"),
                    members: machineMembers);

                return(mainMachineClassDecl);
            }