Пример #1
0
        public SymbolTable CreateFrom(Dafny.Program program, CompilationUnit compilationUnit, CancellationToken cancellationToken)
        {
            var declarations               = CreateDeclarationDictionary(compilationUnit, cancellationToken);
            var designatorVisitor          = new DesignatorVisitor(_logger, program, declarations, compilationUnit, cancellationToken);
            var declarationLocationVisitor = new SymbolDeclarationLocationVisitor(cancellationToken);
            var symbolsResolved            = !HasErrors(program);

            if (symbolsResolved)
            {
                designatorVisitor.Visit(program);
                declarationLocationVisitor.Visit(compilationUnit);
            }
            else
            {
                // TODO This is an unfortunate situation. The syntax could be correct but contain some semantic errors.
                //      However, due to the contracts of the resolver we cannot pro-actively check if certain information could be resolved or not.
                //      Therefore, we only have "all or nothing" when re-using the semantic model. Check if there is really no possibility to
                //      check if information was set without actually retrieving it (i.e., it's not possible to access the Type attribute due to a contract
                //      prohibiting it to be null).
                _logger.LogDebug("cannot create symbol table from a program with errors");
            }
            return(new SymbolTable(
                       compilationUnit,
                       declarations,
                       declarationLocationVisitor.Locations,
                       designatorVisitor.SymbolLookup,
                       symbolsResolved
                       ));
        }
Пример #2
0
        public static ICallable GetCallable(Dafny.Program program, string ModuleName, string ClassName, string LemmaName)
        {
            if (ClassName == "")
            {
                ClassName = "__default";
            }
            var FullName = ModuleName + "." + ClassName + "." + LemmaName;

            foreach (ModuleDefinition module in program.ModuleSigs.Keys)
            {
                if (module.FullName != ModuleName)
                {
                    continue;
                }
                foreach (ICallable callable in module.CallGraph.vertices.Keys)
                {
                    if (callable.FullSanitizedName != FullName)
                    {
                        continue;
                    }
                    return(callable);
                }
            }
            return(null);
        }
Пример #3
0
        public static void RemoveLemmaLinesFlattened(Dafny.Program program, string LemmaName, string ClassName, string ModuleName, int Start)
        {
            // Console.WriteLine("Program module signature size: " + program.ModuleSigs.Count);
            if (ClassName == "")
            {
                ClassName = "__default";
            }
            var FullName = ModuleName + "." + ClassName + "." + LemmaName;

            foreach (ModuleDefinition module in program.ModuleSigs.Keys)
            {
                if (module.FullName != ModuleName)
                {
                    continue;
                }
                //Console.WriteLine("   Module "+module_count+" full name: " + module.FullName);
                foreach (ICallable callable in module.CallGraph.vertices.Keys)
                {
                    var corresVertex = module.CallGraph.vertices[callable];
                    // Console.WriteLine("     Callable "+callable_count+" name: " + callable.NameRelativeToModule);
                    if (callable.WhatKind != "lemma")
                    {
                        continue;
                    }
                    if (callable.FullSanitizedName != FullName)
                    {
                        continue;
                    }
                    var LemmaCallable = (Lemma)callable;
                    var Body          = LemmaCallable.methodBody;
                    int result        = RemoveLemmaLinesFlattenedHelper(Body.Body, Start);
                }
            }
        }
Пример #4
0
        public async Task <string?> VerifyAsync(Dafny.Program program, CancellationToken cancellationToken)
        {
            if (program.reporter.AllMessages[ErrorLevel.Error].Count > 0)
            {
                // TODO Change logic so that the loader is responsible to ensure that the previous steps were sucessful.
                _logger.LogDebug("skipping program verification since the parser or resolvers already reported errors");
                return(null);
            }
            await _mutex.WaitAsync(cancellationToken);

            try {
                // The printer is responsible for two things: It logs boogie errors and captures the counter example model.
                var errorReporter = program.reporter;
                var printer       = new ModelCapturingOutputPrinter(_logger, errorReporter);
                ExecutionEngine.printer = printer;
                var translated = Translator.Translate(program, errorReporter, new Translator.TranslatorFlags {
                    InsertChecksums = true
                });
                foreach (var(_, boogieProgram) in translated)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    VerifyWithBoogie(boogieProgram, cancellationToken);
                }
                return(printer.SerializedCounterExamples);
            } finally {
                _mutex.Release();
            }
        }
 public virtual void Visit(Dafny.Program program)
 {
     foreach (var module in program.Modules())
     {
         Visit(module);
     }
 }
Пример #6
0
        // private BlockStmt ClonedStmt;
        // private Cloner cloner = new Cloner();
        // private string _moduleName;
        // private string _callableName;

        /*
         * public DocumentModifier(Dafny.Program program, string ModuleName, string CallableName){
         *  _moduleName = ModuleName;
         *  _callableName = CallableName;
         *  foreach(ModuleDefinition module in program.ModuleSigs.Keys){
         *      if(module.FullName != _moduleName) continue;
         *      foreach(ICallable callable in module.CallGraph.vertices.Keys){
         *          if(callable.NameRelativeToModule != _callableName) continue;
         *          var LemmaCallable = (Lemma)callable;
         *          var Body = LemmaCallable.methodBody;
         *          // Console.WriteLine("********** Print Original Statement Info ************");
         *          // Console.WriteLine("Cloned Statement count: " + Body.Body.Count);
         *          for(int i = 0; i < Body.Body.Count; ++ i){
         *              DocumentPrinter.PrintStatementInfo(Body.Body[i], "Test ", i, 0);
         *          }
         *          ClonedStmt = cloner.CloneBlockStmt(Body);
         *          // Console.WriteLine("********** Print Cloned Statement Info ************");
         *          // Console.WriteLine("Cloned Statement count: " + ClonedStmt.Body.Count);
         *          for(int i = 0; i < ClonedStmt.Body.Count; ++ i){
         *              DocumentPrinter.PrintStatementInfo(ClonedStmt.Body[i], "Test ", i, 0);
         *          }
         *          break;
         *      }
         *  }
         * }*/
        /*
         * public void RestoreProgram(Dafny.Program program){
         *  foreach(ModuleDefinition module in program.ModuleSigs.Keys){
         *      if(module.FullName != _moduleName) continue;
         *      foreach(ICallable callable in module.CallGraph.vertices.Keys){
         *          if(callable.NameRelativeToModule != _callableName) continue;
         *          var LemmaCallable = (Lemma)callable;
         *          LemmaCallable.methodBody = cloner.CloneBlockStmt(ClonedStmt);
         *      }
         *  }
         * }*/

        public static void RemoveLastLineOfFOO(Dafny.Program program)
        {
            // Console.WriteLine("Program module signature size: " + program.ModuleSigs.Count);
            int module_count = 0;

            foreach (ModuleDefinition module in program.ModuleSigs.Keys)
            {
                // Console.WriteLine("   Module "+module_count+" full name: " + module.FullName);
                int callable_count = 0;
                foreach (ICallable callable in module.CallGraph.vertices.Keys)
                {
                    var corresVertex = module.CallGraph.vertices[callable];
                    // Console.WriteLine("     Callable "+callable_count+" name: " + callable.NameRelativeToModule);
                    if (callable.WhatKind == "lemma")
                    {
                        var LemmaCallable = (Lemma)callable;
                        var Body          = LemmaCallable.methodBody;
                        // Console.WriteLine("     Callable "+callable_count+" #statement " + Body.Body.Count);
                        // Try to remove the last assertion of foo
                        if (callable.NameRelativeToModule == "foo")
                        {
                            Body.Body.Remove(Body.Body.Last());
                            // Console.WriteLine("     Callable "+callable_count+" #statement after deletion " + Body.Body.Count);
                        }
                    }
                    ++callable_count;
                }
                ++module_count;
            }
        }
Пример #7
0
        public static Statement GetStatement(Dafny.Program program, string ModuleName, string ClassName, string LemmaName, int Location)
        {
            if (ClassName == "")
            {
                ClassName = "__default";
            }
            var FullName = ModuleName + "." + ClassName + "." + LemmaName;

            foreach (ModuleDefinition module in program.ModuleSigs.Keys)
            {
                if (module.FullName != ModuleName)
                {
                    continue;
                }
                foreach (ICallable callable in module.CallGraph.vertices.Keys)
                {
                    if (callable.WhatKind != "lemma" || callable.FullSanitizedName != FullName)
                    {
                        continue;
                    }
                    var LemmaCallable = (Lemma)callable;
                    var Body          = LemmaCallable.Body.Body;
                    var End           = GetStatementHelper(Body, Location, out var Result);
                    return(Result);
                }
            }
            return(null);
        }
Пример #8
0
        static Graph <Function> BuildFunctionCallGraph(Dafny.Program program)
        {
            Graph <Function>   functionCallGraph = new Graph <Function>();
            FunctionCallFinder callFinder        = new FunctionCallFinder();

            foreach (var module in program.Modules())
            {
                foreach (var decl in module.TopLevelDecls)
                {
                    if (decl is ClassDecl)
                    {
                        var c = (ClassDecl)decl;
                        foreach (var member in c.Members)
                        {
                            if (member is Function)
                            {
                                var f = (Function)member;

                                List <Function> calls = new List <Function>();
                                foreach (var e in f.Reads)
                                {
                                    if (e != null && e.E != null)
                                    {
                                        callFinder.Visit(e.E, calls);
                                    }
                                }
                                foreach (var e in f.Req)
                                {
                                    if (e != null)
                                    {
                                        callFinder.Visit(e, calls);
                                    }
                                }
                                foreach (var e in f.Ens)
                                {
                                    if (e != null)
                                    {
                                        callFinder.Visit(e, calls);
                                    }
                                }
                                if (f.Body != null)
                                {
                                    callFinder.Visit(f.Body, calls);
                                }

                                foreach (var callee in calls)
                                {
                                    functionCallGraph.AddEdge(f, callee);
                                }
                            }
                        }
                    }
                }
            }

            return(functionCallGraph);
        }
Пример #9
0
 public DesignatorVisitor(
     ILogger logger, Dafny.Program program, IDictionary <AstElement, ILocalizableSymbol> declarations, ISymbol rootScope, CancellationToken cancellationToken
     )
 {
     _logger            = logger;
     _program           = program;
     _declarations      = declarations;
     _typeResolver      = new DafnyLangTypeResolver(declarations);
     _currentScope      = rootScope;
     _cancellationToken = cancellationToken;
 }
Пример #10
0
        private async Task <string?> VerifyIfEnabled(TextDocumentItem textDocument, Dafny.Program program, bool verify, CancellationToken cancellationToken)
        {
            if (!verify)
            {
                return(null);
            }
            _notificationPublisher.Started(textDocument);
            var serializedCounterExamples = await _verifier.VerifyAsync(program, cancellationToken);

            _notificationPublisher.Completed(textDocument, serializedCounterExamples == null);
            return(serializedCounterExamples);
        }
Пример #11
0
        private bool Parse()
        {
            Dafny.ModuleDecl module   = new Dafny.LiteralModuleDecl(new Dafny.DefaultModuleDecl(), null);
            Dafny.BuiltIns   builtIns = new Dafny.BuiltIns();
            var success = (Dafny.Parser.Parse(source, fname, fname, null, module, builtIns, new Dafny.Errors(reporter)) == 0 &&
                           Dafny.Main.ParseIncludes(module, builtIns, new List <string>(), new Dafny.Errors(reporter)) == null);

            if (success)
            {
                dafnyProgram = new Dafny.Program(fname, module, builtIns, reporter);
            }
            return(success);
        }
Пример #12
0
        private bool RunDafnyResolver(TextDocumentItem document, Dafny.Program program)
        {
            var resolver = new Resolver(program);

            resolver.ResolveProgram(program);
            int resolverErrors = GetErrorCount(program);

            if (resolverErrors > 0)
            {
                _logger.LogDebug("encountered {} errors while resolving {}", resolverErrors, document.Uri);
                return(false);
            }
            return(true);
        }
Пример #13
0
        public static void OutputProgramInfo(Dafny.Program program)
        {
            Console.WriteLine("*************** Print Program Info ****************");
            Console.WriteLine("Program name: " + program.FullName);

            Console.WriteLine("Program module signature size: " + program.ModuleSigs.Count);
            int ModuleCount = 0;

            foreach (ModuleDefinition module in program.ModuleSigs.Keys)
            {
                PrintModuleInfo(module, ModuleCount);
                ++ModuleCount;
            }
        }
Пример #14
0
            public CompilationUnit ProcessProgram(Dafny.Program program)
            {
                _cancellationToken.ThrowIfCancellationRequested();
                var compilationUnit = new CompilationUnit(program);

                // program.CompileModules would probably more suitable here, since we want the symbols of the System module as well.
                // However, it appears that the AST of program.CompileModules does not hold the correct location of the nodes - at least of the declarations.
                foreach (var module in program.Modules())
                {
                    compilationUnit.Modules.Add(ProcessModule(compilationUnit, module));
                }
                compilationUnit.Modules.Add(ProcessModule(compilationUnit, program.BuiltIns.SystemModule));
                return(compilationUnit);
            }
 public DafnyDocument(
     TextDocumentItem textDocument,
     ErrorReporter errors,
     Dafny.Program program,
     SymbolTable symbolTable,
     string?serializedCounterExamples
     )
 {
     Text        = textDocument;
     Errors      = errors;
     Program     = program;
     SymbolTable = symbolTable;
     SerializedCounterExamples = serializedCounterExamples;
 }
Пример #16
0
        /// <summary>
        /// Prints the program's function call graph in a format suitable for consumption in other tools
        /// </summary>
        public static void PrintFunctionCallGraph(Dafny.Program program)
        {
            var functionCallGraph = BuildFunctionCallGraph(program);

            foreach (var vertex in functionCallGraph.GetVertices())
            {
                var func = vertex.N;
                Console.Write("{0},{1}=", func.CompileName, func.EnclosingClass.Module.CompileName);
                foreach (var callee in vertex.Successors)
                {
                    Console.Write("{0} ", callee.N.CompileName);
                }
                Console.Write("\n");
            }
        }
Пример #17
0
        public static void RemoveLemmaLines(Dafny.Program program, string LemmaName, string ClassName, string ModuleName, int Start)
        {
            if (ClassName == "")
            {
                ClassName = "__default";
            }
            var FullName = ModuleName + "." + ClassName + "." + LemmaName;

            // Console.WriteLine("Program module signature size: " + program.ModuleSigs.Count);
            foreach (ModuleDefinition module in program.ModuleSigs.Keys)
            {
                if (module.FullName != ModuleName)
                {
                    continue;
                }
                //Console.WriteLine("   Module "+module_count+" full name: " + module.FullName);
                foreach (ICallable callable in module.CallGraph.vertices.Keys)
                {
                    var corresVertex = module.CallGraph.vertices[callable];
                    // Console.WriteLine("     Callable "+callable_count+" name: " + callable.NameRelativeToModule);
                    if (callable.WhatKind != "lemma")
                    {
                        continue;
                    }
                    if (callable.FullSanitizedName != FullName)
                    {
                        continue;
                    }
                    var LemmaCallable = (Lemma)callable;
                    var Body          = LemmaCallable.methodBody;
                    // Console.WriteLine("     Callable "+callable_count+" #statement " + Body.Body.Count);

                    /*
                     * if(Start >= Body.Body.Count){
                     *  Console.WriteLine("Cannot starting position longer than list size!");
                     *  return;
                     * }*/
                    Body.Body.RemoveRange(Start, Body.Body.Count - Start);
                }
            }
        }
        public async Task <string?> VerifyAsyncRecordInfoSpecifyName(Dafny.Program program, CancellationToken cancellationToken,
                                                                     List <Tuple <string, string, string> > callableName, List <long> callableTime,
                                                                     string ModuleName, string ClassName, string LemmaName)
        {
            if (program.reporter.AllMessages[ErrorLevel.Error].Count > 0)
            {
                // TODO Change logic so that the loader is responsible to ensure that the previous steps were sucessful.
                _logger.LogDebug("skipping program verification since the parser or resolvers already reported errors");
                return(null);
            }
            await _mutex.WaitAsync(cancellationToken);

            try {
                string toBeChecked = "*" + ModuleName + "." + ClassName + "." + LemmaName;
                DafnyOptions.O.procsToCheck.Add(toBeChecked);
                // Console.WriteLine(">>>>>>>>>>>> Specify: " + toBeChecked);
                // Console.WriteLine("User Constrained Procs To Check?" + DafnyOptions.O.UserConstrainedProcsToCheck);

                // The printer is responsible for two things: It logs boogie errors and captures the counter example model.
                var errorReporter = program.reporter;
                var printer       = new ModelCapturingOutputPrinter(_logger, errorReporter, callableName, callableTime);
                ExecutionEngine.printer = printer;
                var translated = Translator.Translate(program, errorReporter, new Translator.TranslatorFlags {
                    InsertChecksums = true
                });
                foreach (var(CompileName, boogieProgram) in translated)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    VerifyWithBoogie(boogieProgram, cancellationToken);
                }
                if (DafnyOptions.O.procsToCheck.Count > 0)
                {
                    DafnyOptions.O.procsToCheck.RemoveAt(DafnyOptions.O.procsToCheck.Count - 1);
                }
                return(printer.SerializedCounterExamples);
            } finally {
                _mutex.Release();
            }
        }
        public async Task <string?> VerifyAsyncRecordInfo(Dafny.Program program, CancellationToken cancellationToken)
        {
            if (program.reporter.AllMessages[ErrorLevel.Error].Count > 0)
            {
                // TODO Change logic so that the loader is responsible to ensure that the previous steps were sucessful.
                _logger.LogDebug("skipping program verification since the parser or resolvers already reported errors");
                return(null);
            }
            await _mutex.WaitAsync(cancellationToken);

            try {
                // The printer is responsible for two things: It logs boogie errors and captures the counter example model.
                var errorReporter = program.reporter;
                List <Tuple <string, string, string> > callableName = new List <Tuple <string, string, string> >();
                List <long> callableInfo = new List <long>();
                var         printer      = new ModelCapturingOutputPrinter(_logger, errorReporter, callableName, callableInfo);
                ExecutionEngine.printer = printer;
                var translated = Translator.Translate(program, errorReporter, new Translator.TranslatorFlags {
                    InsertChecksums = true
                });
                foreach (var(CompileName, boogieProgram) in translated)
                {
                    // Console.WriteLine("------------------ Compile name of current boogie program is: " + CompileName  + "---------");
                    cancellationToken.ThrowIfCancellationRequested();
                    VerifyWithBoogie(boogieProgram, cancellationToken);
                }

                /*
                 * Console.WriteLine(">>>>>>>>>>>>>> Callable Name Count: " + callableName.Count + "<<<<<<<<<<<<<<");
                 * Console.WriteLine(">>>>>>>>>>>>>> Callable Info Count: " + callableInfo.Count + "<<<<<<<<<<<<<<");
                 *
                 * for(int i = 0; i < callableName.Count; ++i){
                 * Console.WriteLine(">>>>>>>>>>> Callable #"+i+": " + callableName[i].Item1 + "." + callableName[i].Item2 + "." + callableName[i].Item3 + ", Status: " + callableInfo[i]);
                 * }*/
                return(printer.SerializedCounterExamples);
            } finally {
                _mutex.Release();
            }
        }
Пример #20
0
 private bool Parse()
 {
     Dafny.ModuleDecl module = new Dafny.LiteralModuleDecl(new Dafny.DefaultModuleDecl(), null);
       Dafny.BuiltIns builtIns = new Dafny.BuiltIns();
       var success = (Dafny.Parser.Parse(source, fname, fname, module, builtIns, new Dafny.Errors(reporter)) == 0 &&
              Dafny.Main.ParseIncludes(module, builtIns, new List<string>(), new Dafny.Errors(reporter)) == null);
       if (success) {
     dafnyProgram = new Dafny.Program(fname, module, builtIns, reporter);
       }
       return success;
 }
Пример #21
0
        /// <summary>
        /// Generate a C# program from the Dafny program and, if "invokeCsCompiler" is "true", invoke
        /// the C# compiler to compile it.
        /// </summary>
        public static bool CompileDafnyProgram(Dafny.Program dafnyProgram, string dafnyProgramName,
                                               ReadOnlyCollection <string> otherFileNames, bool invokeCsCompiler,
                                               TextWriter outputWriter = null)
        {
            Contract.Requires(dafnyProgram != null);

            if (outputWriter == null)
            {
                outputWriter = Console.Out;
            }

            // Compile the Dafny program into a string that contains the C# program
            StringWriter sw            = new StringWriter();
            var          oldErrorCount = dafnyProgram.reporter.Count(ErrorLevel.Error);

            Dafny.Compiler compiler = new Dafny.Compiler(dafnyProgram.reporter);
            var            hasMain  = compiler.HasMain(dafnyProgram);

            compiler.Compile(dafnyProgram, sw);
            var  csharpProgram   = sw.ToString();
            bool completeProgram = dafnyProgram.reporter.Count(ErrorLevel.Error) == oldErrorCount;

            // blurt out the code to a file, if requested, or if other files were specified for the C# command line.
            string targetFilename = null;

            if (DafnyOptions.O.SpillTargetCode > 0 || otherFileNames.Count > 0)
            {
                targetFilename = WriteDafnyProgramToFile(dafnyProgramName, csharpProgram, completeProgram, outputWriter);
            }

            // compile the program into an assembly
            if (!completeProgram || !invokeCsCompiler)
            {
                // don't compile
                return(false);
            }
            else if (!CodeDomProvider.IsDefinedLanguage("CSharp"))
            {
                outputWriter.WriteLine("Error: cannot compile, because there is no provider configured for input language CSharp");
                return(false);
            }
            else
            {
                var provider = CodeDomProvider.CreateProvider("CSharp", new Dictionary <string, string> {
                    { "CompilerVersion", "v4.0" }
                });
                var cp = new System.CodeDom.Compiler.CompilerParameters();
                cp.GenerateExecutable = hasMain;
                if (DafnyOptions.O.RunAfterCompile)
                {
                    cp.GenerateInMemory = true;
                }
                else if (hasMain)
                {
                    cp.OutputAssembly   = Path.ChangeExtension(dafnyProgramName, "exe");
                    cp.GenerateInMemory = false;
                }
                else
                {
                    cp.OutputAssembly   = Path.ChangeExtension(dafnyProgramName, "dll");
                    cp.GenerateInMemory = false;
                }
                cp.CompilerOptions = "/debug /nowarn:0164 /nowarn:0219 /nowarn:1717 /nowarn:0162"; // warning CS0164 complains about unreferenced labels, CS0219 is about unused variables, CS1717 is about assignments of a variable to itself, CS0162 is about unreachable code
                cp.ReferencedAssemblies.Add("System.Numerics.dll");
                cp.ReferencedAssemblies.Add("System.Core.dll");
                cp.ReferencedAssemblies.Add("System.dll");

                var libPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + Path.DirectorySeparatorChar;
                if (DafnyOptions.O.UseRuntimeLib)
                {
                    cp.ReferencedAssemblies.Add(libPath + "DafnyRuntime.dll");
                }

                var immutableDllFileName = "System.Collections.Immutable.dll";
                var immutableDllPath     = libPath + immutableDllFileName;

                if (DafnyOptions.O.Optimize)
                {
                    cp.CompilerOptions += " /optimize /define:DAFNY_USE_SYSTEM_COLLECTIONS_IMMUTABLE";
                    cp.ReferencedAssemblies.Add(immutableDllPath);
                    cp.ReferencedAssemblies.Add("System.Runtime.dll");
                }

                int numOtherSourceFiles = 0;
                if (otherFileNames.Count > 0)
                {
                    foreach (var file in otherFileNames)
                    {
                        string extension = Path.GetExtension(file);
                        if (extension != null)
                        {
                            extension = extension.ToLower();
                        }
                        if (extension == ".cs")
                        {
                            numOtherSourceFiles++;
                        }
                        else if (extension == ".dll")
                        {
                            cp.ReferencedAssemblies.Add(file);
                        }
                    }
                }

                CompilerResults cr;
                if (numOtherSourceFiles > 0)
                {
                    string[] sourceFiles = new string[numOtherSourceFiles + 1];
                    sourceFiles[0] = targetFilename;
                    int index = 1;
                    foreach (var file in otherFileNames)
                    {
                        string extension = Path.GetExtension(file);
                        if (extension != null)
                        {
                            extension = extension.ToLower();
                        }
                        if (extension == ".cs")
                        {
                            sourceFiles[index++] = file;
                        }
                    }
                    cr = provider.CompileAssemblyFromFile(cp, sourceFiles);
                }
                else
                {
                    cr = provider.CompileAssemblyFromSource(cp, csharpProgram);
                }

                if (DafnyOptions.O.RunAfterCompile && !hasMain)
                {
                    // do no more
                    return(cr.Errors.Count == 0 ? true : false);
                }

                var assemblyName = Path.GetFileName(cr.PathToAssembly);
                if (DafnyOptions.O.RunAfterCompile && cr.Errors.Count == 0)
                {
                    outputWriter.WriteLine("Program compiled successfully");
                    outputWriter.WriteLine("Running...");
                    outputWriter.WriteLine();
                    var entry = cr.CompiledAssembly.EntryPoint;
                    try {
                        object[] parameters = entry.GetParameters().Length == 0 ? new object[] { } : new object[] { new string[0] };
                        entry.Invoke(null, parameters);
                    } catch (System.Reflection.TargetInvocationException e) {
                        outputWriter.WriteLine("Error: Execution resulted in exception: {0}", e.Message);
                        outputWriter.WriteLine(e.InnerException.ToString());
                    } catch (Exception e) {
                        outputWriter.WriteLine("Error: Execution resulted in exception: {0}", e.Message);
                        outputWriter.WriteLine(e.ToString());
                    }
                }
                else if (cr.Errors.Count == 0)
                {
                    outputWriter.WriteLine("Compiled assembly into {0}", assemblyName);
                    if (DafnyOptions.O.Optimize)
                    {
                        var outputDir = Path.GetDirectoryName(dafnyProgramName);
                        if (string.IsNullOrWhiteSpace(outputDir))
                        {
                            outputDir = ".";
                        }
                        var destPath = outputDir + Path.DirectorySeparatorChar + immutableDllFileName;
                        File.Copy(immutableDllPath, destPath, true);
                        outputWriter.WriteLine("Copied /optimize dependency {0} to {1}", immutableDllFileName, outputDir);
                    }
                }
                else
                {
                    outputWriter.WriteLine("Errors compiling program into {0}", assemblyName);
                    foreach (var ce in cr.Errors)
                    {
                        outputWriter.WriteLine(ce.ToString());
                        outputWriter.WriteLine();
                    }
                    return(false);
                }
                return(true);
            }
        }
Пример #22
0
        /// <summary>
        /// Generate a C# program from the Dafny program and, if "invokeCompiler" is "true", invoke
        /// the C# compiler to compile it.
        /// </summary>
        public static bool CompileDafnyProgram(Dafny.Program dafnyProgram, string dafnyProgramName,
                                               ReadOnlyCollection <string> otherFileNames, bool invokeCompiler,
                                               TextWriter outputWriter = null)
        {
            Contract.Requires(dafnyProgram != null);
            Contract.Assert(dafnyProgramName != null);

            if (outputWriter == null)
            {
                outputWriter = Console.Out;
            }

            // Compile the Dafny program into a string that contains the target program
            var oldErrorCount = dafnyProgram.reporter.Count(ErrorLevel.Error);

            Dafny.Compiler compiler;
            switch (DafnyOptions.O.CompileTarget)
            {
            case DafnyOptions.CompilationTarget.Csharp:
            default:
                compiler = new Dafny.CsharpCompiler(dafnyProgram.reporter);
                break;

            case DafnyOptions.CompilationTarget.JavaScript:
                compiler = new Dafny.JavaScriptCompiler(dafnyProgram.reporter);
                break;

            case DafnyOptions.CompilationTarget.Go:
                compiler = new Dafny.GoCompiler(dafnyProgram.reporter);
                break;

            case DafnyOptions.CompilationTarget.Java:
                compiler = new Dafny.JavaCompiler(dafnyProgram.reporter);
                break;
            }

            Method mainMethod;
            var    hasMain = compiler.HasMain(dafnyProgram, out mainMethod);
            string targetProgramText;
            var    otherFiles = new Dictionary <string, string>();
            {
                var fileQueue = new Queue <FileTargetWriter>();
                using (var wr = new TargetWriter(0)) {
                    compiler.Compile(dafnyProgram, wr);
                    var sw = new StringWriter();
                    wr.Collect(sw, fileQueue);
                    targetProgramText = sw.ToString();
                }

                while (fileQueue.Count > 0)
                {
                    var wr = fileQueue.Dequeue();
                    var sw = new StringWriter();
                    wr.Collect(sw, fileQueue);
                    otherFiles.Add(wr.Filename, sw.ToString());
                }
            }
            string baseName   = Path.GetFileNameWithoutExtension(dafnyProgramName);
            string callToMain = null;

            if (hasMain)
            {
                using (var wr = new TargetWriter(0)) {
                    if (DafnyOptions.O.CompileTarget is DafnyOptions.CompilationTarget.Java)
                    {
                        dafnyProgramName = dafnyProgramName.Replace('-', '_');
                        wr.WriteLine($"public class {baseName.Replace('-', '_')} {{");
                    }
                    compiler.EmitCallToMain(mainMethod, wr);
                    if (DafnyOptions.O.CompileTarget is DafnyOptions.CompilationTarget.Java)
                    {
                        wr.WriteLine("}");
                    }
                    callToMain = wr.ToString(); // assume there aren't multiple files just to call main
                }
            }
            bool completeProgram = dafnyProgram.reporter.Count(ErrorLevel.Error) == oldErrorCount;

            // blurt out the code to a file, if requested, or if other files were specified for the C# command line.
            string targetFilename = null;

            if (DafnyOptions.O.SpillTargetCode > 0 || otherFileNames.Count > 0 || (invokeCompiler && !compiler.SupportsInMemoryCompilation))
            {
                var p = callToMain == null ? targetProgramText : targetProgramText + callToMain;
                if (DafnyOptions.O.CompileTarget is DafnyOptions.CompilationTarget.Java && callToMain == null)
                {
                    p = null;
                }
                targetFilename = WriteDafnyProgramToFiles(dafnyProgramName, p, completeProgram, otherFiles, outputWriter);
            }

            if (DafnyOptions.O.CompileTarget is DafnyOptions.CompilationTarget.Java)
            {
                string targetBaseDir    = baseName;
                string targetDir        = Path.Combine(Path.GetDirectoryName(dafnyProgramName), targetBaseDir);
                var    assemblyLocation = System.Reflection.Assembly.GetExecutingAssembly().Location;
                Contract.Assert(assemblyLocation != null);
                var codebase = System.IO.Path.GetDirectoryName(assemblyLocation);
                Contract.Assert(codebase != null);
                string dest = targetDir + "/dafny";
                Directory.CreateDirectory(dest);
                var jcompiler = (JavaCompiler)compiler;
                jcompiler.CompileTuples(dest);
                jcompiler.CreateFunctionInterface(dest);
                jcompiler.CompileDafnyArrays(dest);
                jcompiler.CompileArrayInits(dest);
            }

            if (!completeProgram)
            {
                return(false);
            }
            // If we got until here, compilation to C# succeeded
            if (!invokeCompiler)
            {
                return(true); // If we're not asked to invoke the C# to assembly compiler, we can report success
            }

            // compile the program into an assembly
            object compilationResult;
            var    compiledCorrectly = compiler.CompileTargetProgram(dafnyProgramName, targetProgramText, callToMain, targetFilename, otherFileNames,
                                                                     hasMain, hasMain && DafnyOptions.O.RunAfterCompile, outputWriter, out compilationResult);

            if (compiledCorrectly && DafnyOptions.O.RunAfterCompile)
            {
                if (hasMain)
                {
                    if (DafnyOptions.O.CompileVerbose)
                    {
                        outputWriter.WriteLine("Running...");
                        outputWriter.WriteLine();
                    }
                    compiledCorrectly = compiler.RunTargetProgram(dafnyProgramName, targetProgramText, callToMain, targetFilename, otherFileNames, compilationResult, outputWriter);
                }
                else
                {
                    // make sure to give some feedback to the user
                    if (DafnyOptions.O.CompileVerbose)
                    {
                        outputWriter.WriteLine("Program compiled successfully");
                    }
                }
            }
            return(compiledCorrectly);
        }
 public CompilationUnit(Dafny.Program program) : base(null, program.Name)
 {
     Program = program;
 }
Пример #24
0
 private static int GetErrorCount(Dafny.Program program)
 {
     return(program.reporter.AllMessages[ErrorLevel.Error].Count);
 }
Пример #25
0
        public async Task <CompilationUnit> ResolveSymbolsAsync(TextDocumentItem textDocument, Dafny.Program program, CancellationToken cancellationToken)
        {
            int parserErrors = GetErrorCount(program);

            if (parserErrors > 0)
            {
                _logger.LogTrace("document {} had {} parser errors, skipping symbol resolution", textDocument.Uri, parserErrors);
                return(new CompilationUnit(program));
            }

            // TODO The resolution requires mutual exclusion since it sets static variables of classes like Microsoft.Dafny.Type.
            //      Although, the variables are marked "ThreadStatic" - thus it might not be necessary. But there might be
            //      other classes as well.
            await _resolverMutex.WaitAsync(cancellationToken);

            try {
                if (!RunDafnyResolver(textDocument, program))
                {
                    // We cannot proceeed without a successful resolution. Due to the contracts in dafny-lang, we cannot
                    // access a property without potential contract violations. For example, a variable may have an
                    // unresolved type represented by null. However, the contract prohibits the use of the type property
                    // because it must not be null.
                    return(new CompilationUnit(program));
                }
            } finally {
                _resolverMutex.Release();
            }
            return(new SymbolDeclarationResolver(_logger, cancellationToken).ProcessProgram(program));
        }
Пример #26
0
        /// <summary>
        /// Generate a C# program from the Dafny program and, if "invokeCompiler" is "true", invoke
        /// the C# compiler to compile it.
        /// </summary>
        public static bool CompileDafnyProgram(Dafny.Program dafnyProgram, string dafnyProgramName,
                                               ReadOnlyCollection <string> otherFileNames, bool invokeCompiler,
                                               TextWriter outputWriter = null)
        {
            Contract.Requires(dafnyProgram != null);
            Contract.Assert(dafnyProgramName != null);

            if (outputWriter == null)
            {
                outputWriter = Console.Out;
            }

            // Compile the Dafny program into a string that contains the target program
            var oldErrorCount = dafnyProgram.reporter.Count(ErrorLevel.Error);

            Dafny.Compiler compiler;
            switch (DafnyOptions.O.CompileTarget)
            {
            case DafnyOptions.CompilationTarget.Csharp:
            default:
                compiler = new Dafny.CsharpCompiler(dafnyProgram.reporter);
                break;

            case DafnyOptions.CompilationTarget.JavaScript:
                compiler = new Dafny.JavaScriptCompiler(dafnyProgram.reporter);
                break;

            case DafnyOptions.CompilationTarget.Go:
                compiler = new Dafny.GoCompiler(dafnyProgram.reporter);
                break;

            case DafnyOptions.CompilationTarget.Java:
                compiler = new Dafny.JavaCompiler(dafnyProgram.reporter);
                break;

            case DafnyOptions.CompilationTarget.Cpp:
                compiler = new Dafny.CppCompiler(dafnyProgram.reporter, otherFileNames);
                break;
            }

            var hasMain = compiler.HasMain(dafnyProgram, out var mainMethod);

            if (hasMain)
            {
                mainMethod.IsEntryPoint = true;
                dafnyProgram.MainMethod = mainMethod;
            }
            string targetProgramText;
            var    otherFiles = new Dictionary <string, string>();
            {
                var output = new ConcreteSyntaxTree();
                compiler.Compile(dafnyProgram, output);
                var writerOptions           = new WriterState();
                var targetProgramTextWriter = new StringWriter();
                var files = new Queue <FileSyntax>();
                output.Render(targetProgramTextWriter, 0, writerOptions, files);
                targetProgramText = targetProgramTextWriter.ToString();

                while (files.Count > 0)
                {
                    var file            = files.Dequeue();
                    var otherFileWriter = new StringWriter();
                    writerOptions.HasNewLine = false;
                    file.Tree.Render(otherFileWriter, 0, writerOptions, files);
                    otherFiles.Add(file.Filename, otherFileWriter.ToString());
                }
            }
            string callToMain = null;

            if (hasMain)
            {
                var    callToMainTree = new ConcreteSyntaxTree();
                string baseName       = Path.GetFileNameWithoutExtension(dafnyProgramName);
                compiler.EmitCallToMain(mainMethod, baseName, callToMainTree);
                callToMain = callToMainTree.ToString(); // assume there aren't multiple files just to call main
            }
            Contract.Assert(hasMain == (callToMain != null));
            bool targetProgramHasErrors = dafnyProgram.reporter.Count(ErrorLevel.Error) != oldErrorCount;

            compiler.Coverage.WriteLegendFile();

            // blurt out the code to a file, if requested, or if other target-language files were specified on the command line.
            string targetFilename = null;

            if (DafnyOptions.O.SpillTargetCode > 0 || otherFileNames.Count > 0 || (invokeCompiler && !compiler.SupportsInMemoryCompilation) ||
                (invokeCompiler && compiler.TextualTargetIsExecutable && !DafnyOptions.O.RunAfterCompile))
            {
                targetFilename = WriteDafnyProgramToFiles(compiler, dafnyProgramName, targetProgramHasErrors, targetProgramText, callToMain, otherFiles, outputWriter);
            }

            if (targetProgramHasErrors)
            {
                return(false);
            }
            // If we got here, compilation succeeded
            if (!invokeCompiler)
            {
                return(true); // If we're not asked to invoke the target compiler, we can report success
            }

            // compile the program into an assembly
            var compiledCorrectly = compiler.CompileTargetProgram(dafnyProgramName, targetProgramText, callToMain, targetFilename, otherFileNames,
                                                                  hasMain && DafnyOptions.O.RunAfterCompile, outputWriter, out var compilationResult);

            if (compiledCorrectly && DafnyOptions.O.RunAfterCompile)
            {
                if (hasMain)
                {
                    if (DafnyOptions.O.CompileVerbose)
                    {
                        outputWriter.WriteLine("Running...");
                        outputWriter.WriteLine();
                    }
                    compiledCorrectly = compiler.RunTargetProgram(dafnyProgramName, targetProgramText, callToMain, targetFilename, otherFileNames, compilationResult, outputWriter);
                }
                else
                {
                    // make sure to give some feedback to the user
                    if (DafnyOptions.O.CompileVerbose)
                    {
                        outputWriter.WriteLine("Program compiled successfully");
                    }
                }
            }
            return(compiledCorrectly);
        }
Пример #27
0
        /// <summary>
        /// Generate a C# program from the Dafny program and, if "invokeCompiler" is "true", invoke
        /// the C# compiler to compile it.
        /// </summary>
        public static bool CompileDafnyProgram(Dafny.Program dafnyProgram, string dafnyProgramName,
                                               ReadOnlyCollection <string> otherFileNames, bool invokeCompiler,
                                               TextWriter outputWriter = null)
        {
            Contract.Requires(dafnyProgram != null);
            Contract.Assert(dafnyProgramName != null);

            if (outputWriter == null)
            {
                outputWriter = Console.Out;
            }

            // Compile the Dafny program into a string that contains the target program
            var oldErrorCount = dafnyProgram.reporter.Count(ErrorLevel.Error);

            Dafny.Compiler compiler;
            switch (DafnyOptions.O.CompileTarget)
            {
            case DafnyOptions.CompilationTarget.Csharp:
            default:
                compiler = new Dafny.CsharpCompiler(dafnyProgram.reporter);
                break;

            case DafnyOptions.CompilationTarget.JavaScript:
                compiler = new Dafny.JavaScriptCompiler(dafnyProgram.reporter);
                break;

            case DafnyOptions.CompilationTarget.Go:
                compiler = new Dafny.GoCompiler(dafnyProgram.reporter);
                break;
            }

            Method mainMethod;
            var    hasMain = compiler.HasMain(dafnyProgram, out mainMethod);
            string targetProgramText;
            var    otherFiles = new Dictionary <string, string>();
            {
                var fileQueue = new Queue <FileTargetWriter>();
                using (var wr = new TargetWriter(0)) {
                    compiler.Compile(dafnyProgram, wr);
                    var sw = new StringWriter();
                    wr.Collect(sw, fileQueue);
                    targetProgramText = sw.ToString();
                }

                while (fileQueue.Count > 0)
                {
                    var wr = fileQueue.Dequeue();
                    var sw = new StringWriter();
                    wr.Collect(sw, fileQueue);
                    otherFiles.Add(wr.Filename, sw.ToString());
                }
            }
            string callToMain = null;

            if (hasMain)
            {
                using (var wr = new TargetWriter(0)) {
                    compiler.EmitCallToMain(mainMethod, wr);
                    callToMain = wr.ToString(); // assume there aren't multiple files just to call main
                }
            }
            bool completeProgram = dafnyProgram.reporter.Count(ErrorLevel.Error) == oldErrorCount;

            // blurt out the code to a file, if requested, or if other files were specified for the C# command line.
            string targetFilename = null;

            if (DafnyOptions.O.SpillTargetCode > 0 || otherFileNames.Count > 0 || (invokeCompiler && !compiler.SupportsInMemoryCompilation))
            {
                var p = callToMain == null ? targetProgramText : targetProgramText + callToMain;
                targetFilename = WriteDafnyProgramToFiles(dafnyProgramName, p, completeProgram, otherFiles, outputWriter);
            }

            // compile the program into an assembly
            if (!completeProgram || !invokeCompiler)
            {
                // don't compile
                return(false);
            }

            object compilationResult;
            var    compiledCorrectly = compiler.CompileTargetProgram(dafnyProgramName, targetProgramText, callToMain, targetFilename, otherFileNames,
                                                                     hasMain, hasMain && DafnyOptions.O.RunAfterCompile, outputWriter, out compilationResult);

            if (compiledCorrectly && DafnyOptions.O.RunAfterCompile)
            {
                if (hasMain)
                {
                    if (DafnyOptions.O.CompileVerbose)
                    {
                        outputWriter.WriteLine("Running...");
                        outputWriter.WriteLine();
                    }
                    compiledCorrectly = compiler.RunTargetProgram(dafnyProgramName, targetProgramText, callToMain, targetFilename, otherFileNames, compilationResult, outputWriter);
                }
                else
                {
                    // make sure to give some feedback to the user
                    if (DafnyOptions.O.CompileVerbose)
                    {
                        outputWriter.WriteLine("Program compiled successfully");
                    }
                }
            }
            return(compiledCorrectly);
        }
Пример #28
0
        /// <summary>
        /// Compute various interesting statistics about the Dafny program
        /// </summary>
        public static void PrintStats(Dafny.Program program)
        {
            SortedDictionary <string, ulong> stats = new SortedDictionary <string, ulong>();

            foreach (var module in program.Modules())
            {
                IncrementStat(stats, "Modules");
                UpdateMax(stats, "Module height (max)", (ulong)module.Height);

                ulong num_scc = (ulong)module.CallGraph.TopologicallySortedComponents().Count;
                UpdateMax(stats, "Call graph width (max)", num_scc);

                foreach (var decl in module.TopLevelDecls)
                {
                    if (decl is DatatypeDecl)
                    {
                        IncrementStat(stats, "Datatypes");
                    }
                    else if (decl is ClassDecl)
                    {
                        var c = (ClassDecl)decl;
                        if (c.Name != "_default")
                        {
                            IncrementStat(stats, "Classes");
                        }

                        foreach (var member in c.Members)
                        {
                            if (member is Function)
                            {
                                IncrementStat(stats, "Functions (total)");
                                var f = (Function)member;
                                if (f.IsRecursive)
                                {
                                    IncrementStat(stats, "Functions recursive");
                                }
                            }
                            else if (member is Method)
                            {
                                IncrementStat(stats, "Methods (total)");
                                var method = (Method)member;
                                if (method.IsRecursive)
                                {
                                    IncrementStat(stats, "Methods recursive");
                                }
                                if (method.IsGhost)
                                {
                                    IncrementStat(stats, "Methods ghost");
                                }
                            }
                        }
                    }
                }
            }

            // Print out the results, with some nice formatting
            Console.WriteLine("");
            Console.WriteLine("Statistics");
            Console.WriteLine("----------");

            int max_key_length = 0;

            foreach (var key in stats.Keys)
            {
                if (key.Length > max_key_length)
                {
                    max_key_length = key.Length;
                }
            }

            foreach (var keypair in stats)
            {
                string keyString = keypair.Key.PadRight(max_key_length + 2);
                Console.WriteLine("{0} {1,4}", keyString, keypair.Value);
            }
        }
Пример #29
0
 /// <summary>
 /// Checks if the given token is part of the entrypoint document.
 /// </summary>
 /// <param name="program">The dafny program to check the token against.</param>
 /// <param name="token">The token to check.</param>
 /// <returns><c>true</c> if the given token is part of the entrypoint document of the given program.</returns>
 public static bool IsPartOfEntryDocument(this Dafny.Program program, Boogie.IToken token)
 {
     // The token filename happens to be null if it's representing a default module or class.
     return(token.filename == null || token.filename == program.FullName);
 }
Пример #30
0
 /// <summary>
 /// Checks if the given URI is the entrypoint document.
 /// </summary>
 /// <param name="program">The dafny program to check the token against.</param>
 /// <param name="documentUri">The URI to check.</param>
 /// <returns><c>true</c> if the given URI is the entrypoint document of the given program.</returns>
 public static bool IsEntryDocument(this Dafny.Program program, DocumentUri documentUri)
 {
     return(GetFilePath(documentUri) == program.FullName);
 }
Пример #31
0
 private static bool HasErrors(Dafny.Program program)
 {
     // TODO create extension method
     return(program.reporter.AllMessages[ErrorLevel.Error].Count > 0);
 }