diff --git a/Source/DafnyCore/AST/Modules/ModuleDefinition.cs b/Source/DafnyCore/AST/Modules/ModuleDefinition.cs index 5e53a1961ad..22ab1f784d1 100644 --- a/Source/DafnyCore/AST/Modules/ModuleDefinition.cs +++ b/Source/DafnyCore/AST/Modules/ModuleDefinition.cs @@ -177,12 +177,13 @@ public string SanitizedName { public string GetCompileName(DafnyOptions options) { if (compileName == null) { var externArgs = options.DisallowExterns ? null : Attributes.FindExpressions(this.Attributes, "extern"); + var nonExternSuffix = (options.Get(CommonOptionBag.AddCompileSuffix) ? "_Compile" : ""); if (externArgs != null && 1 <= externArgs.Count && externArgs[0] is StringLiteralExpr) { compileName = (string)((StringLiteralExpr)externArgs[0]).Value; } else if (externArgs != null) { - compileName = Name; + compileName = Name + nonExternSuffix; } else { - compileName = SanitizedName; + compileName = SanitizedName + nonExternSuffix; } } diff --git a/Source/DafnyCore/Compilers/Java/Compiler-java.cs b/Source/DafnyCore/Compilers/Java/Compiler-java.cs index 3218376e766..459e03508b5 100644 --- a/Source/DafnyCore/Compilers/Java/Compiler-java.cs +++ b/Source/DafnyCore/Compilers/Java/Compiler-java.cs @@ -335,7 +335,12 @@ public override void EmitCallToMain(Method mainMethod, string baseName, Concrete var companion = TypeName_Companion(UserDefinedType.FromTopLevelDeclWithAllBooleanTypeParameters(mainMethod.EnclosingClass), wr, mainMethod.tok, mainMethod); var wBody = wr.NewNamedBlock("public static void main(String[] args)"); - var modName = mainMethod.EnclosingClass.EnclosingModuleDefinition.GetCompileName(Options) == "_module" ? "_System." : ""; + var addCompileSuffix = Options.Get(CommonOptionBag.AddCompileSuffix); + var defaultModuleCompileName = addCompileSuffix ? "_module_Compile" : "_module"; + var enclosingModuleCompileNAme = mainMethod.EnclosingClass.EnclosingModuleDefinition.GetCompileName(Options); + var modName = enclosingModuleCompileNAme == defaultModuleCompileName + ? (addCompileSuffix ? "_System_Compile." : "_System.") + : ""; companion = modName + companion; Coverage.EmitSetup(wBody); wBody.WriteLine($"{DafnyHelpersClass}.withHaltHandling(() -> {{ {companion}.__Main({DafnyHelpersClass}.{CharMethodQualifier}FromMainArguments(args)); }} );"); diff --git a/Source/DafnyCore/DafnyOptions.cs b/Source/DafnyCore/DafnyOptions.cs index 735d12591f1..5e81545f248 100644 --- a/Source/DafnyCore/DafnyOptions.cs +++ b/Source/DafnyCore/DafnyOptions.cs @@ -124,6 +124,8 @@ void ParsePrintMode(Option option, Bpl.CommandLineParseState ps, Daf } } } + + RegisterLegacyUi(CommonOptionBag.AddCompileSuffix, ParseBoolean, "Compilation options", "compileSuffix"); } public void ApplyBinding(Option option) { diff --git a/Source/DafnyCore/Options/CommonOptionBag.cs b/Source/DafnyCore/Options/CommonOptionBag.cs index cdd3198788e..228ed28284a 100644 --- a/Source/DafnyCore/Options/CommonOptionBag.cs +++ b/Source/DafnyCore/Options/CommonOptionBag.cs @@ -9,6 +9,11 @@ namespace Microsoft.Dafny; public class CommonOptionBag { + public static readonly Option AddCompileSuffix = + new("--compile-suffix", "Add the suffix _Compile to module names without :extern") { + IsHidden = true + }; + public static readonly Option ManualLemmaInduction = new("--manual-lemma-induction", "Turn off automatic induction for lemmas."); @@ -290,6 +295,9 @@ static CommonOptionBag() { // target language code from referencing compiled internal code, // so to be conservative we flag this as not compatible in general. { OptimizeErasableDatatypeWrapper, DooFile.CheckOptionMatches }, + // Similarly this shouldn't matter if external code ONLY refers to {:extern}s, + // but in practice it does. + { AddCompileSuffix, DooFile.CheckOptionMatches } } ); DooFile.RegisterNoChecksNeeded( diff --git a/Source/DafnyCore/Options/ICommandSpec.cs b/Source/DafnyCore/Options/ICommandSpec.cs index e7d570783ae..097bb23bdbc 100644 --- a/Source/DafnyCore/Options/ICommandSpec.cs +++ b/Source/DafnyCore/Options/ICommandSpec.cs @@ -49,7 +49,8 @@ static ICommandSpec() { CommonOptionBag.EnforceDeterminism, CommonOptionBag.OptimizeErasableDatatypeWrapper, CommonOptionBag.TestAssumptions, - DeveloperOptionBag.Bootstrapping + DeveloperOptionBag.Bootstrapping, + CommonOptionBag.AddCompileSuffix, }.Concat(VerificationOptions).ToList(); public static IReadOnlyList