Example #1
0
        public static string GetCanonicalFunctionName(FunctionDefinition funcDef, TranslatorContext context)
        {
            ContractDefinition contract = context.GetContractByFunction(funcDef);
            string             paramStr = "";

            if (funcDef.Parameters != null)
            {
                foreach (VariableDeclaration paramDecl in funcDef.Parameters.Parameters)
                {
                    String typeStr = "";
                    if (paramDecl.TypeName is Mapping map)
                    {
                        typeStr = "map" + map.KeyType.ToString();
                    }
                    else if (paramDecl.TypeName is UserDefinedTypeName userDef)
                    {
                        typeStr = userDef.Name;
                    }
                    else if (paramDecl.TypeName is ArrayTypeName arr)
                    {
                        typeStr = "arr";
                    }
                    else
                    {
                        typeStr = paramDecl.TypeName.ToString().Replace(" ", "");
                    }

                    paramStr = $"{paramStr}~{typeStr}";
                }
            }

            return($"{funcDef.Name}{paramStr}_{contract.Name}");
            //return funcDef.Name + "_" + contract.Name;
        }
 public static bool IsUsingBasedLibraryCall(TranslatorContext context, ContractDefinition curContract, MemberAccess memberAccess)
 {
     // since we only permit "using A for B" for non-contract types
     // this is sufficient, but not necessary in general since non
     // contracts (including libraries) do not have support methods
     return(GetUsedLibrary(context, curContract, memberAccess) != null);
 }
        public static bool IsExternalFunctionCall(TranslatorContext context, FunctionCall node)
        {
            if (node.Expression is MemberAccess memberAccess)
            {
                if (memberAccess.Expression is Identifier identifier)
                {
                    if (identifier.Name == "this")
                    {
                        return(true);
                    }

                    if (identifier.Name == "super")
                    {
                        return(true);
                    }

                    if (!context.HasASTNodeId(identifier.ReferencedDeclaration))
                    {
                        return(true);
                    }

                    var contract = context.GetASTNodeById(identifier.ReferencedDeclaration) as ContractDefinition;
                    if (contract == null)
                    {
                        return(true);
                    }
                }
                else if (memberAccess.Expression is MemberAccess structSelect)
                {
                    //a.b.c.foo(...)
                    //TODO: do we want to check that the contract the struct variable is declared
                    // is not in the "context"? Why this isn't done for IndexAccess?
                    return(true);
                }
                else if (memberAccess.Expression.ToString().Equals("msg.sender"))
                {
                    // calls can be of the form "msg.sender.call()" or "msg.sender.send()" or "msg.sender.transfer()"
                    return(true);
                }
                else if (memberAccess.Expression is FunctionCall)
                {
                    // TODO: example?
                    return(true);
                }
                else if (memberAccess.Expression is IndexAccess)
                {
                    //a[i].foo(..)
                    return(true);
                }
                else if (memberAccess.Expression is TupleExpression)
                {
                    return(true);
                }
            }
            return(false);
        }
 public static bool IsStaticDispatching(TranslatorContext context, FunctionCall node)
 {
     if (node.Expression is MemberAccess memberAccess)
     {
         if (memberAccess.Expression is Identifier ident)
         {
             if (context.GetASTNodeById(ident.ReferencedDeclaration) is ContractDefinition)
             {
                 return(true);
             }
         }
     }
     return(false);
 }
        public static ContractDefinition GetStaticDispatchingContract(TranslatorContext context, FunctionCall node)
        {
            VeriSolAssert(node.Expression is MemberAccess);
            MemberAccess memberAccess = node.Expression as MemberAccess;

            Identifier contractId = memberAccess.Expression as Identifier;

            VeriSolAssert(contractId != null, $"Unknown contract name: {memberAccess.Expression}");

            ContractDefinition contract = context.GetASTNodeById(contractId.ReferencedDeclaration) as ContractDefinition;

            VeriSolAssert(contract != null);
            return(contract);
        }
 public static ContractDefinition IsLibraryFunctionCall(TranslatorContext context, FunctionCall node)
 {
     if (node.Expression is MemberAccess memberAccess)
     {
         if (memberAccess.Expression is Identifier identifier)
         {
             var contract = context.GetASTNodeById(identifier.ReferencedDeclaration) as ContractDefinition;
             // a Library is treated as an external function call
             // we need to do it here as the Lib.Foo, Lib is not an expression but name of a contract
             if (contract.ContractKind == EnumContractKind.LIBRARY)
             {
                 return(contract);
             }
         }
     }
     return(null);
 }
Example #7
0
        public static string InferFunctionSignature(TranslatorContext context, FunctionCall node,
                                                    bool forceNameLookup = false)
        {
            Debug.Assert(node.Arguments != null);

            if (!forceNameLookup && node.Expression is MemberAccess memberAccess)
            {
                Debug.Assert(memberAccess.ReferencedDeclaration != null);
                FunctionDefinition function = context.GetASTNodeById(memberAccess.ReferencedDeclaration.Value) as FunctionDefinition;
                Debug.Assert(function != null, $"Could not find function {node.ToString()}");
                StringBuilder builder = new StringBuilder();
                builder.Append(function.Name).Append("(");
                if (function.Parameters.Parameters != null && function.Parameters.Parameters.Count > 0)
                {
                    foreach (VariableDeclaration varDecl in function.Parameters.Parameters)
                    {
                        //builder.Append(varDecl.TypeDescriptions.TypeString).Append(", ");
                        builder.Append(InferTypeFromTypeString(varDecl.TypeDescriptions.TypeString)).Append(", ");
                    }
                    builder.Length -= 2;
                }
                builder.Append(")");
                return(builder.ToString());
            }
            else
            {
                string        functionName = GetFuncNameFromFuncCall(node);
                StringBuilder builder      = new StringBuilder();
                builder.Append(functionName).Append("(");
                if (node.Arguments.Count > 0)
                {
                    foreach (Expression argument in node.Arguments)
                    {
                        string typeString = InferTypeFromTypeString(argument.TypeDescriptions.TypeString);
                        builder.Append(typeString).Append(", ");
                    }
                    builder.Length -= 2;
                }
                builder.Append(")");
                return(builder.ToString());
            }
        }
Example #8
0
        public static BoogieStmtList constrainVarValues(TranslatorContext context, VariableDeclaration var, BoogieIdentifierExpr boogieVar)
        {
            BoogieStmtList stmts = new BoogieStmtList();

            if (context.TranslateFlags.UseModularArithmetic)
            {
                if (var.TypeDescriptions.IsUintWSize(null, out uint uintSize))
                {
                    BigInteger            maxUIntValue = (BigInteger)Math.Pow(2, uintSize);
                    BoogieBinaryOperation lower        = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.GE, boogieVar, new BoogieLiteralExpr(BigInteger.Zero));
                    BoogieBinaryOperation upper        = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.LT, boogieVar, new BoogieLiteralExpr(maxUIntValue));
                    stmts.AddStatement(new BoogieAssumeCmd(new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.AND, lower, upper)));
                }
                else if (var.TypeDescriptions.IsIntWSize(out uint intSize))
                {
                    BigInteger            maxIntValue = (BigInteger)Math.Pow(2, intSize);
                    BoogieBinaryOperation lower       = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.GE, boogieVar, new BoogieLiteralExpr(-maxIntValue));
                    BoogieBinaryOperation upper       = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.LT, boogieVar, new BoogieLiteralExpr(maxIntValue));
                    stmts.AddStatement(new BoogieAssumeCmd(new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.AND, lower, upper)));
                }
            }

            return(stmts);
        }
Example #9
0
        public static string GetCanonicalStateVariableName(VariableDeclaration varDecl, TranslatorContext context)
        {
            Debug.Assert(varDecl.StateVariable, $"{varDecl.Name} is not a state variable");

            Dictionary <VariableDeclaration, ContractDefinition> varToContractMap = context.StateVarToContractMap;

            Debug.Assert(varToContractMap.ContainsKey(varDecl), $"Cannot find state variable: {varDecl.Name}");
            return(varDecl.Name + "_" + varToContractMap[varDecl].Name);
        }
Example #10
0
 public FunctionEventCollector(TranslatorContext context)
 {
     this.context = context;
 }
Example #11
0
 public static string GetCanonicalVariableName(VariableDeclaration varDecl, TranslatorContext context)
 {
     return(varDecl.StateVariable ? GetCanonicalStateVariableName(varDecl, context) : GetCanonicalLocalVariableName(varDecl));
 }
Example #12
0
 public HarnessGenerator(TranslatorContext context, Dictionary <string, List <BoogieExpr> > _contractInvariants)
 {
     this.context            = context;
     this.contractInvariants = _contractInvariants;
 }
Example #13
0
 public GhostVarAndAxiomGenerator(TranslatorContext context)
 {
     this.context = context;
 }
Example #14
0
        // returns a map from integer id to an atomic Boogie predicate
        public static Dictionary <int, BoogieExpr> GenerateHoudiniVarMapping(ContractDefinition contract, TranslatorContext context)
        {
            Dictionary <int, BoogieExpr>  ret       = new Dictionary <int, BoogieExpr>();
            HashSet <VariableDeclaration> stateVars = context.GetVisibleStateVarsByContract(contract);

            // collect all state variables of type address
            List <VariableDeclaration> addressVariables = new List <VariableDeclaration>();

            foreach (VariableDeclaration stateVar in stateVars)
            {
                if (stateVar.TypeName is ElementaryTypeName elementaryType)
                {
                    if (elementaryType.TypeDescriptions.TypeString.Equals("address") ||
                        elementaryType.TypeDescriptions.TypeString.Equals("address payable"))
                    {
                        addressVariables.Add(stateVar);
                    }
                }
            }

            int id = 0;

            // equaility and disequality to null
            foreach (VariableDeclaration addressVar in addressVariables)
            {
                BoogieExpr lhs      = GetBoogieExprOfStateVar(addressVar, context);
                BoogieExpr rhs      = new BoogieIdentifierExpr("null");
                BoogieExpr equality = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.EQ, lhs, rhs);
                ret[++id] = equality;
                BoogieExpr disequality = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.NEQ, lhs, rhs);
                ret[++id] = disequality;
            }

            // pair-wise equality and disequality
            for (int i = 0; i < addressVariables.Count; ++i)
            {
                BoogieExpr lhs = GetBoogieExprOfStateVar(addressVariables[i], context);
                for (int j = i + 1; j < addressVariables.Count; ++j)
                {
                    BoogieExpr rhs      = GetBoogieExprOfStateVar(addressVariables[j], context);
                    BoogieExpr equality = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.EQ, lhs, rhs);
                    ret[++id] = equality;
                    BoogieExpr disequality = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.NEQ, lhs, rhs);
                    ret[++id] = disequality;
                }
            }

            // PrintHoudiniCandidateMap(ret);
            return(ret);
        }
        public ERC20SpecGenerator(TranslatorContext context, AST solidityAST, String entryPoint)
        {
            this.context      = context;
            this.solidityAST  = solidityAST;
            varDecls          = new Dictionary <string, VariableDeclaration>();
            fnContracts       = new Dictionary <string, ContractDefinition>();
            otherVars         = new List <VariableDeclaration>();
            declToContractInd = new Dictionary <VariableDeclaration, int>();

            foreach (ContractDefinition def in context.ContractDefinitions)
            {
                if (def.Name.Equals(entryPoint))
                {
                    entryContract = def;
                }
            }

            int contractInd = 0;

            foreach (int id in entryContract.LinearizedBaseContracts)
            {
                contractInd++;
                ContractDefinition contract = context.GetASTNodeById(id) as ContractDefinition;

                if (context.ContractToStateVarsMap.ContainsKey(contract))
                {
                    otherVars.AddRange(context.ContractToStateVarsMap[contract]);
                    foreach (VariableDeclaration decl in context.ContractToStateVarsMap[contract])
                    {
                        declToContractInd[decl] = contractInd;
                    }
                }

                if (!context.ContractToFunctionsMap.ContainsKey(contract))
                {
                    continue;
                }

                HashSet <FunctionDefinition> fnDefs = context.ContractToFunctionsMap[contract];

                foreach (FunctionDefinition fnDef in fnDefs)
                {
                    if (ERC20fns.Contains(fnDef.Name) && !fnContracts.ContainsKey(fnDef.Name))
                    {
                        fnContracts[fnDef.Name] = contract;
                    }

                    if (ERC20Vars.Contains(fnDef.Name) && !varDecls.ContainsKey(fnDef.Name))
                    {
                        ReturnDeclarationFinder declFinder = new ReturnDeclarationFinder(context);
                        VariableDeclaration     decl       = declFinder.findDecl(contract, fnDef);

                        if (decl != null)
                        {
                            varDecls[fnDef.Name] = decl;
                        }
                    }
                }
            }

            foreach (VariableDeclaration decl in varDecls.Values)
            {
                otherVars.Remove(decl);
            }

            otherVars.RemoveAll(v => v.Constant);
        }
Example #16
0
 public ConstructorCollector(TranslatorContext context)
 {
     this.context = context;
 }
Example #17
0
 public ModifierCollector(TranslatorContext context)
 {
     this.context = context;
 }
Example #18
0
 public static Tuple <string, int> GenerateSourceInfoAnnotation(ASTNode node, TranslatorContext context)
 {
     return(Tuple.Create <string, int>(context.GetAbsoluteSourcePathOfASTNode(node), context.GetLineNumberOfASTNode(node)));
 }
Example #19
0
        public static string GetCanonicalFunctionName(FunctionDefinition funcDef, TranslatorContext context)
        {
            ContractDefinition contract = context.GetContractByFunction(funcDef);

            return(funcDef.Name + "_" + contract.Name);
        }
Example #20
0
        private static BoogieMapSelect GetBoogieExprOfStateVar(VariableDeclaration varDecl, TranslatorContext context)
        {
            string          name      = TransUtils.GetCanonicalStateVariableName(varDecl, context);
            BoogieMapSelect mapSelect = new BoogieMapSelect(new BoogieIdentifierExpr(name), new BoogieIdentifierExpr("this"));

            return(mapSelect);
        }
 public StateVariableCollector(TranslatorContext context)
 {
     this.context = context;
 }
Example #22
0
        // set of method@contract pairs whose translatin is skipped
        public BoogieAST Translate(AST solidityAST, HashSet <Tuple <string, string> > ignoredMethods, TranslatorFlags _translatorFlags = null)
        {
            bool generateInlineAttributesInBpl = _translatorFlags.GenerateInlineAttributes;

            SourceUnitList sourceUnits = solidityAST.GetSourceUnits();

            TranslatorContext context = new TranslatorContext(ignoredMethods, generateInlineAttributesInBpl, _translatorFlags);

            context.IdToNodeMap     = solidityAST.GetIdToNodeMap();
            context.SourceDirectory = solidityAST.SourceDirectory;

            // collect the absolute source path and line number for each AST node
            SourceInfoCollector sourceInfoCollector = new SourceInfoCollector(context);

            sourceUnits.Accept(sourceInfoCollector);

            // de-sugar the solidity AST
            // will modify the AST
            SolidityDesugaring desugaring = new SolidityDesugaring(context);

            sourceUnits.Accept(desugaring);

            // collect all contract definitions
            ContractCollector contractCollector = new ContractCollector(context);

            sourceUnits.Accept(contractCollector);

            // collect all sub types for each contract
            InheritanceCollector inheritanceCollector = new InheritanceCollector(context);

            inheritanceCollector.Collect();

            // collect explicit state variables
            StateVariableCollector stateVariableCollector = new StateVariableCollector(context);

            sourceUnits.Accept(stateVariableCollector);

            // resolve state variable declarations and determine the visible ones for each contract
            StateVariableResolver stateVariableResolver = new StateVariableResolver(context);

            stateVariableResolver.Resolve();

            // collect mappings and arrays
            MapArrayCollector mapArrayCollector = new MapArrayCollector(context);

            sourceUnits.Accept(mapArrayCollector);

            // collect constructor definitions
            ConstructorCollector constructorCollector = new ConstructorCollector(context);

            sourceUnits.Accept(constructorCollector);

            // collect explicit function and event definitions
            FunctionEventCollector functionEventCollector = new FunctionEventCollector(context);

            sourceUnits.Accept(functionEventCollector);

            // resolve function and event definitions and determine the actual definition for a dynamic type
            FunctionEventResolver functionEventResolver = new FunctionEventResolver(context);

            functionEventResolver.Resolve();

            // add types, gobal ghost variables, and axioms
            GhostVarAndAxiomGenerator generator = new GhostVarAndAxiomGenerator(context);

            generator.Generate();

            // collect modifiers information
            ModifierCollector modifierCollector = new ModifierCollector(context);

            sourceUnits.Accept(modifierCollector);

            // translate procedures
            ProcedureTranslator procTranslator = new ProcedureTranslator(context, generateInlineAttributesInBpl);

            sourceUnits.Accept(procTranslator);

            // generate fallbacks
            FallbackGenerator fallbackGenerator = new FallbackGenerator(context);

            fallbackGenerator.Generate();

            // generate harness for each contract
            if (!context.TranslateFlags.NoHarness)
            {
                HarnessGenerator harnessGenerator = new HarnessGenerator(context, procTranslator.ContractInvariants);
                harnessGenerator.Generate();
            }

            if (context.TranslateFlags.ModelReverts)
            {
                RevertLogicGenerator reverGenerator = new RevertLogicGenerator(context);
                reverGenerator.Generate();
            }

            return(new BoogieAST(context.Program));
        }
Example #23
0
        public static string InferFunctionSignature(TranslatorContext context, FunctionCall node)
        {
            Debug.Assert(node.Arguments != null);

            if (node.Expression is MemberAccess memberAccess)
            {
                Debug.Assert(memberAccess.ReferencedDeclaration != null);
                FunctionDefinition function = context.GetASTNodeById(memberAccess.ReferencedDeclaration.Value) as FunctionDefinition;
                Debug.Assert(function != null, $"Could not find function {node.ToString()}");
                StringBuilder builder = new StringBuilder();
                builder.Append(function.Name).Append("(");
                if (function.Parameters.Parameters != null && function.Parameters.Parameters.Count > 0)
                {
                    foreach (VariableDeclaration varDecl in function.Parameters.Parameters)
                    {
                        builder.Append(varDecl.TypeDescriptions.TypeString).Append(", ");
                    }
                    builder.Length -= 2;
                }
                builder.Append(")");
                return(builder.ToString());
            }
            else
            {
                string        functionName = GetFuncNameFromFunctionCall(node);
                StringBuilder builder      = new StringBuilder();
                builder.Append(functionName).Append("(");
                if (node.Arguments.Count > 0)
                {
                    foreach (Expression argument in node.Arguments)
                    {
                        string typeString = argument.TypeDescriptions.TypeString;
                        if (typeString.StartsWith("int_const"))
                        {
                            typeString = "int256";
                        }
                        if (typeString.StartsWith("uint_const"))
                        {
                            typeString = "int256";
                        }
                        if (typeString.StartsWith("string") || typeString.StartsWith("literal_string"))
                        {
                            typeString = "string";
                        }
                        if (typeString.StartsWith("bytes "))
                        {
                            typeString = "bytes";           //"bytes storage ref"
                        }
                        if (typeString.Contains(" memory")) //"struct Foo memory"
                        {
                            typeString = typeString.Substring(0, typeString.IndexOf(" memory"));
                        }
                        if (typeString.Contains(" storage"))
                        {
                            typeString = typeString.Substring(0, typeString.IndexOf(" storage"));
                        }
                        builder.Append(typeString).Append(", ");
                    }
                    builder.Length -= 2;
                }
                builder.Append(")");
                return(builder.ToString());
            }
        }
        public static ContractDefinition GetUsedLibrary(TranslatorContext context, ContractDefinition curContract,
                                                        MemberAccess memberAccess)
        {
            FunctionDefinition fnDef = context.GetASTNodeById(memberAccess.ReferencedDeclaration.Value) as FunctionDefinition;

            if (fnDef == null || !context.FunctionToContractMap.ContainsKey(fnDef))
            {
                return(null);
            }

            ContractDefinition fnContract = context.GetContractByFunction(fnDef);

            Dictionary <ContractDefinition, UserDefinedTypeName> usingLibs = new Dictionary <ContractDefinition, UserDefinedTypeName>();
            List <int> contractIds = new List <int>();

            contractIds.Add(curContract.Id);
            contractIds.AddRange(curContract.LinearizedBaseContracts);

            foreach (int id in contractIds)
            {
                ContractDefinition baseContract = context.GetASTNodeById(id) as ContractDefinition;

                foreach (UserDefinedTypeName typeName in context.UsingMap[baseContract].Keys)
                {
                    ContractDefinition libDef = context.GetASTNodeById(typeName.ReferencedDeclaration) as ContractDefinition;
                    if (!usingLibs.ContainsKey(libDef))
                    {
                        usingLibs[libDef] = typeName;
                    }
                }
            }

            if (usingLibs.ContainsKey(fnContract))
            {
                if (memberAccess.Expression.TypeDescriptions.IsContract() &&
                    !memberAccess.Expression.TypeDescriptions.IsArray())
                {
                    //search sub-types
                    UserDefinedTypeName libType = usingLibs[fnContract];
                    String                       contractName = memberAccess.Expression.TypeDescriptions.TypeString.Split(" ")[1];
                    ContractDefinition           contractDef  = context.GetContractByName(contractName);
                    HashSet <ContractDefinition> usedBy       = context.UsingMap[curContract][libType].FindAll(t =>
                                                                                                               t is UserDefinedTypeName u &&
                                                                                                               context.GetASTNodeById(u.ReferencedDeclaration) is ContractDefinition).Select(c =>
                                                                                                                                                                                             context.GetASTNodeById(((UserDefinedTypeName)(c))
                                                                                                                                                                                                                    .ReferencedDeclaration) as ContractDefinition).ToHashSet();

                    bool usesLib = usedBy.Contains(contractDef);

                    foreach (int id in contractDef.LinearizedBaseContracts)
                    {
                        ContractDefinition baseContract = context.GetASTNodeById(id) as ContractDefinition;
                        if (usedBy.Contains(baseContract))
                        {
                            usesLib = true;
                        }
                    }

                    return(usesLib ? fnContract : null);
                }
                else
                {
                    return(fnContract);
                }
            }

            return(null);
        }
Example #25
0
 public RevertLogicGenerator(TranslatorContext context)
 {
     this.context          = context;
     this.constructorNames = context.ContractDefinitions.Select(c => TransUtils.GetCanonicalConstructorName(c)).ToHashSet();
     proceduresInProgram   = context.Program.Declarations.OfType <BoogieProcedure>().ToDictionary(procedure => procedure.Name);
 }
Example #26
0
 public FallbackGenerator(TranslatorContext _context)
 {
     context = _context;
 }
Example #27
0
 public ModifierCollector(TranslatorContext context)
 {
     this.context         = context;
     this.localTranslator = new ProcedureTranslator(context);
 }
Example #28
0
 public ContractCollector(TranslatorContext context)
 {
     this.context = context;
 }
        // set of method@contract pairs whose translatin is skipped
        public BoogieAST Translate(AST solidityAST, HashSet <Tuple <string, string> > ignoredMethods, bool generateInlineAttributesInBpl)
        {
            if (generateInlineAttributesInBpl)
            {
                Console.WriteLine($"Warning! Found /noInlineAttrs option...the generated Bpl file cannot be used for unbounded verification");
            }

            SourceUnitList sourceUnits = solidityAST.GetSourceUnits();

            TranslatorContext context = new TranslatorContext(ignoredMethods, generateInlineAttributesInBpl);

            context.IdToNodeMap     = solidityAST.GetIdToNodeMap();
            context.SourceDirectory = solidityAST.SourceDirectory;

            // collect the absolute source path and line number for each AST node
            SourceInfoCollector sourceInfoCollector = new SourceInfoCollector(context);

            sourceUnits.Accept(sourceInfoCollector);

            // de-sugar the solidity AST
            // will modify the AST
            SolidityDesugaring desugaring = new SolidityDesugaring(context);

            sourceUnits.Accept(desugaring);

            // collect all contract definitions
            ContractCollector contractCollector = new ContractCollector(context);

            sourceUnits.Accept(contractCollector);

            // collect all sub types for each contract
            InheritanceCollector inheritanceCollector = new InheritanceCollector(context);

            inheritanceCollector.Collect();

            // collect explicit state variables
            StateVariableCollector stateVariableCollector = new StateVariableCollector(context);

            sourceUnits.Accept(stateVariableCollector);

            // resolve state variable declarations and determine the visible ones for each contract
            StateVariableResolver stateVariableResolver = new StateVariableResolver(context);

            stateVariableResolver.Resolve();

            // collect mappings and arrays
            MapArrayCollector mapArrayCollector = new MapArrayCollector(context);

            sourceUnits.Accept(mapArrayCollector);

            // collect constructor definitions
            ConstructorCollector constructorCollector = new ConstructorCollector(context);

            sourceUnits.Accept(constructorCollector);

            // collect explicit function and event definitions
            FunctionEventCollector functionEventCollector = new FunctionEventCollector(context);

            sourceUnits.Accept(functionEventCollector);

            // resolve function and event definitions and determine the actual definition for a dynamic type
            FunctionEventResolver functionEventResolver = new FunctionEventResolver(context);

            functionEventResolver.Resolve();

            // add types, gobal ghost variables, and axioms
            GhostVarAndAxiomGenerator generator = new GhostVarAndAxiomGenerator(context);

            generator.Generate();

            // collect modifiers information
            ModifierCollector modifierCollector = new ModifierCollector(context);

            sourceUnits.Accept(modifierCollector);

            // translate procedures
            ProcedureTranslator procTranslator = new ProcedureTranslator(context, generateInlineAttributesInBpl);

            sourceUnits.Accept(procTranslator);

            // generate harness for each contract
            HarnessGenerator harnessGenerator = new HarnessGenerator(context);

            harnessGenerator.Generate();

            return(new BoogieAST(context.Program));
        }
 public ReturnDeclarationFinder(TranslatorContext context)
 {
     this.context = context;
     retDecl      = null;
 }