Beispiel #1
0
        /// <summary>
        /// Generates the Viper text that contains fields and the initializer of this class.
        /// </summary>
        /// <param name="process">The TranslationProcess.</param>
        public Silvernode GenerateGlobalSilvernode(TranslationProcess process)
        {
            var node = new SimpleSequenceSilvernode(null);

            // Translate fields
            foreach (CollectedField field in this.InstanceFields)
            {
                node.List.Add("field ");
                node.List.Add(new IdentifierSilvernode(field.Name));
                node.List.Add(": ");
                node.List.Add(new TypeSilvernode(null, field.SilverType));
                if (this.InstanceFields[this.InstanceFields.Count - 1] != field)
                {
                    node.List.Add("\n");
                }
            }

            // Translate the initializer/default constructor
            if (!this._isStatic)
            {
                Identifier initializer = process.IdentifierTranslator.RegisterAndGetIdentifierWithTag(this.ClassSymbol,
                                                                                                      Constants.InitializerTag);

                // The initializer gives write access to all fields
                var accessToAllFields = new List <ContractSilvernode>();
                foreach (CollectedField field in this.InstanceFields)
                {
                    var protectedField = new SimpleSequenceSilvernode(null,
                                                                      Constants.SilverThis,
                                                                      ".",
                                                                      new IdentifierSilvernode(field.Name)
                                                                      );
                    accessToAllFields.Add(new EnsuresSilvernode(new AccSilvernode(protectedField, "write", null), null));
                }

                var initializerContents = new BlockSilvernode(null, new List <StatementSilvernode>());
                initializerContents.Add(new AssignmentSilvernode(Constants.SilverThis, new NewStarSilvernode(null), null));

                var initializerMethod = new MethodSilvernode(null,
                                                             new IdentifierSilvernode(initializer),
                                                             new List <ParameterSilvernode>(),
                                                             Constants.SilverThis,
                                                             new TypeSilvernode(null, SilverType.Ref),
                                                             accessToAllFields,
                                                             initializerContents);

                node.List.Add("\n");
                node.List.Add(initializerMethod);
            }

            return(node);
        }
        public override TranslationResult Translate(TranslationContext context)
        {
            var  statements  = new List <StatementSilvernode>();
            var  contracts   = new List <ContractSilvernode>();
            var  diagnostics = new List <Error>();
            bool inFunctionOrPredicateBlockReturnStatementAlreadyOccured = false;


            foreach (var statement in this.Statements)
            {
                var statementResult = statement.Translate(context);

                // Prepending statements (part 1)
                if (statementResult.PrependTheseSilvernodes.Any())
                {
                    statements.AddRange(statementResult.PrependTheseSilvernodes);
                }

                if (statementResult.Silvernode != null)
                {
                    // Report an error is a contract is in an invalid block
                    if (statementResult.Silvernode.IsContract())
                    {
                        contracts.Add(statementResult.Silvernode as ContractSilvernode);
                        if (statementResult.Silvernode is RequiresSilvernode ||
                            statementResult.Silvernode is EnsuresSilvernode)
                        {
                            if (this.BlockSyntax.Parent is MethodDeclarationSyntax ||
                                this.BlockSyntax.Parent is ConstructorDeclarationSyntax)
                            {
                            }
                            else
                            {
                                diagnostics.Add(new Translation.Error(
                                                    Diagnostics.SSIL129_MethodContractsAreOnlyForMethods,
                                                    statementResult.Silvernode.OriginalNode));
                            }
                        }
                        if (statementResult.Silvernode is InvariantSilvernode)
                        {
                            if (this.BlockSyntax.Parent is ForStatementSyntax ||
                                this.BlockSyntax.Parent is WhileStatementSyntax ||
                                this.BlockSyntax.Parent is DoStatementSyntax)
                            {
                            }
                            else
                            {
                                diagnostics.Add(new Translation.Error(
                                                    Diagnostics.SSIL130_InvariantsAreOnlyForLoops,
                                                    statementResult.Silvernode.OriginalNode));
                            }
                        }
                    }
                    else
                    {
                        // Translate body
                        if (context.IsFunctionOrPredicateBlock)
                        {
                            if (statement.GetType() == typeof(ReturnStatementSharpnode))
                            {
                                if (inFunctionOrPredicateBlockReturnStatementAlreadyOccured)
                                {
                                    diagnostics.Add(new Error(Diagnostics.SSIL122_FunctionsAndPredicatesCannotHaveMoreThanOneReturnStatement,
                                                              statement.OriginalNode));
                                }
                                else
                                {
                                    inFunctionOrPredicateBlockReturnStatementAlreadyOccured = true;
                                }
                            }
                            else
                            {
                                diagnostics.Add(new Error(Diagnostics.SSIL121_FunctionsAndPredicatesCannotHaveStatements,
                                                          statement.OriginalNode));
                            }
                        }
                        StatementSilvernode statementSilvernode;
                        if ((statementResult.Silvernode is StatementSilvernode))
                        {
                            statementSilvernode = (StatementSilvernode)statementResult.Silvernode;
                        }
                        else
                        {
                            statementSilvernode = new ExpressionStatementSilvernode(statementResult.Silvernode, statementResult.Silvernode.OriginalNode);
                        }
                        statements.Add(statementSilvernode);
                    }
                }
                diagnostics.AddRange(statementResult.Errors);
            }
            BlockSilvernode block = new BlockSilvernode(this.BlockSyntax, statements);

            contracts.Sort();
            return(new TranslationResult
            {
                Silvernode = block,
                Errors = diagnostics,
                Contracts = contracts
            });
        }