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 )); }
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); }
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); } } }
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); } }
// 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; } }
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); }
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); }
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; }
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); }
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); }
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); }
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; } }
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; }
/// <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"); } }
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(); } }
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; }
/// <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); } }
/// <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; }
private static int GetErrorCount(Dafny.Program program) { return(program.reporter.AllMessages[ErrorLevel.Error].Count); }
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)); }
/// <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); }
/// <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); }
/// <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); } }
/// <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); }
/// <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); }
private static bool HasErrors(Dafny.Program program) { // TODO create extension method return(program.reporter.AllMessages[ErrorLevel.Error].Count > 0); }