Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chore: Generated Id are now declaration-specific #5669

Merged
merged 10 commits into from
Aug 8, 2024

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions Source/DafnyCore/AST/CompilationData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
namespace Microsoft.Dafny;

public class CompilationData {
public readonly FreshIdGenerator IdGenerator = new();

public CompilationData(ErrorReporter errorReporter, List<Include> includes, IList<Uri> rootSourceUris, ISet<Uri> alreadyVerifiedRoots, ISet<Uri> alreadyCompiledRoots) {
Includes = includes;
ErrorReporter = errorReporter;
Expand Down
10 changes: 5 additions & 5 deletions Source/DafnyCore/AST/Expressions/Variables/Formal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ public Formal(IToken tok, string name, Type type, bool inParam, bool isGhost, Ex

public bool HasName => !Name.StartsWith("#");

private string sanitizedName;
public override string SanitizedName =>
sanitizedName ??= SanitizeName(Name); // No unique-ification
public override string CompileName =>
compileName ??= SanitizeName(NameForCompilation);
public override string GetOrCreateCompileName(CodeGenIdGenerator generator) {
return CompileName;
}

public string CompileName => compileName ??= SanitizeName(NameForCompilation);

public override IEnumerable<INode> Children =>
(DefaultValue != null ? new List<Node> { DefaultValue } : Enumerable.Empty<Node>()).Concat(base.Children);
Expand Down
20 changes: 8 additions & 12 deletions Source/DafnyCore/AST/Expressions/Variables/IVariable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,14 @@ string UniqueName {
bool HasBeenAssignedUniqueName { // unique names are not assigned until the Translator; if you don't already know if that stage has run, this boolean method will tell you
get;
}
static FreshIdGenerator CompileNameIdGenerator = new FreshIdGenerator();
string AssignUniqueName(FreshIdGenerator generator);
string SanitizedName {
get;
}
string SanitizedNameShadowable { // A name suitable for compilation, but without the unique identifier.
// Useful to generate readable identifiers in the generated source code.
get;
}
string CompileName {
get;
}
string AssignUniqueName(VerificationIdGenerator generator);

/// <summary>
/// A name suitable for compilation, but without the unique identifier.
/// Useful to generate readable identifiers in the generated source code.
/// </summary>
string CompileNameShadowable { get; }
string GetOrCreateCompileName(CodeGenIdGenerator generator);

PreType PreType {
get;
Expand Down
20 changes: 8 additions & 12 deletions Source/DafnyCore/AST/Expressions/Variables/IVariableContracts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,20 @@ public bool HasBeenAssignedUniqueName {
throw new NotImplementedException(); // this getter implementation is here only so that the Ensures contract can be given here
}
}
public string SanitizedName {
get {
Contract.Ensures(Contract.Result<string>() != null);
throw new NotImplementedException(); // this getter implementation is here only so that the Ensures contract can be given here
}
public string SanitizedName(CodeGenIdGenerator generator) {
Contract.Ensures(Contract.Result<string>() != null);
throw new NotImplementedException(); // this getter implementation is here only so that the Ensures contract can be given here
}

public string SanitizedNameShadowable {
public string CompileNameShadowable {
get {
Contract.Ensures(Contract.Result<string>() != null);
throw new NotImplementedException(); // this getter implementation is here only so that the Ensures contract can be given here
}
}
public string CompileName {
get {
Contract.Ensures(Contract.Result<string>() != null);
throw new NotImplementedException(); // this getter implementation is here only so that the Ensures contract can be given here
}
public string GetOrCreateCompileName(CodeGenIdGenerator generator) {
Contract.Ensures(Contract.Result<string>() != null);
throw new NotImplementedException(); // this getter implementation is here only so that the Ensures contract can be given here
}
public Type Type {
get {
Expand Down Expand Up @@ -88,7 +84,7 @@ public bool IsGhost {
public void MakeGhost() {
throw new NotImplementedException();
}
public string AssignUniqueName(FreshIdGenerator generator) {
public string AssignUniqueName(VerificationIdGenerator generator) {
Contract.Ensures(Contract.Result<string>() != null);
throw new NotImplementedException();
}
Expand Down
14 changes: 6 additions & 8 deletions Source/DafnyCore/AST/Expressions/Variables/NonglobalVariable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public string Name {
private string uniqueName;
public string UniqueName => uniqueName;
public bool HasBeenAssignedUniqueName => uniqueName != null;
public string AssignUniqueName(FreshIdGenerator generator) {
public string AssignUniqueName(VerificationIdGenerator generator) {
return uniqueName ??= generator.FreshId(Name + "#");
}

Expand Down Expand Up @@ -87,16 +87,14 @@ public static string SanitizeName(string nm) {

private string sanitizedNameShadowable;

public virtual string SanitizedNameShadowable =>
public virtual string CompileNameShadowable =>
sanitizedNameShadowable ??= SanitizeName(Name);

private string sanitizedName;
public virtual string SanitizedName =>
sanitizedName ??= $"_{IVariable.CompileNameIdGenerator.FreshNumericId()}_{SanitizedNameShadowable}";

protected string compileName;
public virtual string CompileName =>
compileName ??= SanitizedName;

public virtual string GetOrCreateCompileName(CodeGenIdGenerator generator) {
return compileName ??= $"_{generator.FreshNumericId()}_{CompileNameShadowable}";
}

Type type;
public bool IsTypeExplicit { get; set; }
Expand Down
2 changes: 2 additions & 0 deletions Source/DafnyCore/AST/Members/ConstantField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public override bool CanBeRevealed() {
public ModuleDefinition EnclosingModule { get { return this.EnclosingClass.EnclosingModuleDefinition; } }
public bool MustReverify { get { return false; } }
public bool AllowsNontermination { get { throw new cce.UnreachableException(); } }
CodeGenIdGenerator ICodeContext.CodeGenIdGenerator => CodeGenIdGenerator;

public string NameRelativeToModule {
get {
if (EnclosingClass is DefaultClassDecl) {
Expand Down
2 changes: 2 additions & 0 deletions Source/DafnyCore/AST/Members/Function.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ public bool AllowsNontermination {
}
}

CodeGenIdGenerator ICodeContext.CodeGenIdGenerator => CodeGenIdGenerator;

/// <summary>
/// The "AllCalls" field is used for non-ExtremePredicate, non-PrefixPredicate functions only (so its value should not be relied upon for ExtremePredicate and PrefixPredicate functions).
/// It records all function calls made by the Function, including calls made in the body as well as in the specification.
Expand Down
6 changes: 5 additions & 1 deletion Source/DafnyCore/AST/Members/ICodeContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public interface ICodeContext : IASTVisitorContext {
bool MustReverify { get; }
string FullSanitizedName { get; }
bool AllowsNontermination { get; }
CodeGenIdGenerator CodeGenIdGenerator { get; }
}


Expand All @@ -37,6 +38,7 @@ public CodeContextWrapper(ICodeContext inner, bool isGhostContext) {
public bool MustReverify => inner.MustReverify;
public string FullSanitizedName => inner.FullSanitizedName;
public bool AllowsNontermination => inner.AllowsNontermination;
CodeGenIdGenerator ICodeContext.CodeGenIdGenerator => inner.CodeGenIdGenerator;

public static ICodeContext Unwrap(ICodeContext codeContext) {
while (codeContext is CodeContextWrapper ccw) {
Expand Down Expand Up @@ -129,6 +131,8 @@ public NoContext(ModuleDefinition module) {
bool ICodeContext.MustReverify { get { Contract.Assume(false, "should not be called on NoContext"); throw new cce.UnreachableException(); } }
public string FullSanitizedName { get { Contract.Assume(false, "should not be called on NoContext"); throw new cce.UnreachableException(); } }
public bool AllowsNontermination { get { Contract.Assume(false, "should not be called on NoContext"); throw new cce.UnreachableException(); } }
CodeGenIdGenerator ICodeContext.CodeGenIdGenerator { get; } = new();

public bool AllowsAllocation => true;
}

Expand All @@ -144,7 +148,7 @@ public interface RedirectingTypeDecl : ICallable {
Expression/*?*/ Constraint { get; }
SubsetTypeDecl.WKind WitnessKind { get; }
Expression/*?*/ Witness { get; } // non-null iff WitnessKind is Compiled or Ghost
FreshIdGenerator IdGenerator { get; }
VerificationIdGenerator IdGenerator { get; }

[FilledInDuringResolution] bool ConstraintIsCompilable { get; set; }
}
2 changes: 2 additions & 0 deletions Source/DafnyCore/AST/Members/Method.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ public bool AllowsNontermination {
}
}

CodeGenIdGenerator ICodeContext.CodeGenIdGenerator => CodeGenIdGenerator;

public override string GetCompileName(DafnyOptions options) {
var nm = base.GetCompileName(options);
if (nm == Dafny.Compilers.SinglePassCodeGenerator.DefaultNameMain && IsStatic && !IsEntryPoint) {
Expand Down
1 change: 1 addition & 0 deletions Source/DafnyCore/AST/Modules/ModuleDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Diagnostics.Contracts;
using System.Linq;
using Microsoft.Dafny.Auditor;
using Microsoft.Dafny.Compilers;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;

namespace Microsoft.Dafny;
Expand Down
15 changes: 6 additions & 9 deletions Source/DafnyCore/AST/Statements/Assignment/LocalVariable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,23 +65,20 @@ public string DisplayName {
private string uniqueName;
public string UniqueName => uniqueName;
public bool HasBeenAssignedUniqueName => uniqueName != null;
public string AssignUniqueName(FreshIdGenerator generator) {
public string AssignUniqueName(VerificationIdGenerator generator) {
return uniqueName ??= generator.FreshId(Name + "#");
}

private string sanitizedNameShadowable;

public string SanitizedNameShadowable =>
public string CompileNameShadowable =>
sanitizedNameShadowable ??= NonglobalVariable.SanitizeName(Name);

private string sanitizedName;

public string SanitizedName =>
sanitizedName ??= $"_{IVariable.CompileNameIdGenerator.FreshNumericId()}_{SanitizedNameShadowable}";

string compileName;
public string CompileName =>
compileName ??= SanitizedName;

public string GetOrCreateCompileName(CodeGenIdGenerator generator) {
return compileName ??= $"_{generator.FreshNumericId()}_{CompileNameShadowable}";
}

// TODO rename and update comment? Or make it nullable?
public readonly Type SyntacticType; // this is the type mentioned in the declaration, if any
Expand Down
1 change: 1 addition & 0 deletions Source/DafnyCore/AST/TypeDeclarations/DatatypeDecl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public bool IsRecordType {
ModuleDefinition IASTVisitorContext.EnclosingModule { get { return EnclosingModuleDefinition; } }
bool ICodeContext.MustReverify { get { return false; } }
bool ICodeContext.AllowsNontermination { get { return false; } }
CodeGenIdGenerator ICodeContext.CodeGenIdGenerator => CodeGenIdGenerator;
string ICallable.NameRelativeToModule { get { return Name; } }
Specification<Expression> ICallable.Decreases {
get {
Expand Down
7 changes: 6 additions & 1 deletion Source/DafnyCore/AST/TypeDeclarations/Declaration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,14 @@ public override string ToString() {
return Name;
}

internal FreshIdGenerator IdGenerator = new();
// For Boogie
internal VerificationIdGenerator IdGenerator = new();
public override IEnumerable<INode> Children => (Attributes != null ? new List<Node> { Attributes } : Enumerable.Empty<Node>());
public override IEnumerable<INode> PreResolveChildren => Children;
public abstract SymbolKind? Kind { get; }
public abstract string GetDescription(DafnyOptions options);


// For Compilation
internal CodeGenIdGenerator CodeGenIdGenerator = new();
}
3 changes: 3 additions & 0 deletions Source/DafnyCore/AST/TypeDeclarations/IteratorDecl.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using Microsoft.Dafny.Compilers;

namespace Microsoft.Dafny;

Expand Down Expand Up @@ -151,6 +152,8 @@ public bool AllowsNontermination {
}
}

CodeGenIdGenerator ICodeContext.CodeGenIdGenerator => CodeGenIdGenerator;

public override bool SetIndent(int indentBefore, TokenNewIndentCollector formatter) {
formatter.SetMethodLikeIndent(StartToken, OwnedTokens, indentBefore);
foreach (var req in Requires) {
Expand Down
3 changes: 2 additions & 1 deletion Source/DafnyCore/AST/TypeDeclarations/NewtypeDecl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public TypeParameter.EqualitySupportValue EqualitySupport {
Expression RedirectingTypeDecl.Constraint { get { return Constraint; } }
SubsetTypeDecl.WKind RedirectingTypeDecl.WitnessKind { get { return WitnessKind; } }
Expression RedirectingTypeDecl.Witness { get { return Witness; } }
FreshIdGenerator RedirectingTypeDecl.IdGenerator { get { return IdGenerator; } }
VerificationIdGenerator RedirectingTypeDecl.IdGenerator { get { return IdGenerator; } }

bool ICodeContext.IsGhost {
get { throw new NotSupportedException(); } // if .IsGhost is needed, the object should always be wrapped in an CodeContextWrapper
Expand All @@ -126,6 +126,7 @@ bool ICodeContext.IsGhost {
ModuleDefinition IASTVisitorContext.EnclosingModule { get { return EnclosingModuleDefinition; } }
bool ICodeContext.MustReverify { get { return false; } }
bool ICodeContext.AllowsNontermination { get { return false; } }
CodeGenIdGenerator ICodeContext.CodeGenIdGenerator => CodeGenIdGenerator;
string ICallable.NameRelativeToModule { get { return Name; } }
Specification<Expression> ICallable.Decreases {
get {
Expand Down
3 changes: 2 additions & 1 deletion Source/DafnyCore/AST/TypeDeclarations/TypeSynonymDeclBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ bool RedirectingTypeDecl.ConstraintIsCompilable {

SubsetTypeDecl.WKind RedirectingTypeDecl.WitnessKind { get { return SubsetTypeDecl.WKind.CompiledZero; } }
Expression RedirectingTypeDecl.Witness { get { return null; } }
FreshIdGenerator RedirectingTypeDecl.IdGenerator { get { return IdGenerator; } }
VerificationIdGenerator RedirectingTypeDecl.IdGenerator { get { return IdGenerator; } }

bool ICodeContext.IsGhost {
get { throw new NotSupportedException(); } // if .IsGhost is needed, the object should always be wrapped in an CodeContextWrapper
Expand All @@ -83,6 +83,7 @@ bool ICodeContext.IsGhost {
ModuleDefinition IASTVisitorContext.EnclosingModule { get { return EnclosingModuleDefinition; } }
bool ICodeContext.MustReverify { get { return false; } }
bool ICodeContext.AllowsNontermination { get { return false; } }
CodeGenIdGenerator ICodeContext.CodeGenIdGenerator => CodeGenIdGenerator;
string ICallable.NameRelativeToModule { get { return Name; } }
Specification<Expression> ICallable.Decreases {
get {
Expand Down
10 changes: 5 additions & 5 deletions Source/DafnyCore/Backends/CSharp/CsharpCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2046,18 +2046,18 @@ protected override void EmitHalt(IToken tok, Expression/*?*/ messageExpr, Concre
protected override ConcreteSyntaxTree EmitForStmt(IToken tok, IVariable loopIndex, bool goingUp, string /*?*/ endVarName,
List<Statement> body, LList<Label> labels, ConcreteSyntaxTree wr) {

wr.Write($"for ({TypeName(loopIndex.Type, wr, tok)} {loopIndex.CompileName} = ");
wr.Write($"for ({TypeName(loopIndex.Type, wr, tok)} {loopIndex.GetOrCreateCompileName(currentIdGenerator)} = ");
var startWr = wr.Fork();
wr.Write($"; ");

ConcreteSyntaxTree bodyWr;
if (goingUp) {
wr.Write(endVarName != null ? $"{loopIndex.CompileName} < {endVarName}" : "");
bodyWr = wr.NewBlock($"; {loopIndex.CompileName}++)");
wr.Write(endVarName != null ? $"{loopIndex.GetOrCreateCompileName(currentIdGenerator)} < {endVarName}" : "");
bodyWr = wr.NewBlock($"; {loopIndex.GetOrCreateCompileName(currentIdGenerator)}++)");
} else {
wr.Write(endVarName != null ? $"{endVarName} < {loopIndex.CompileName}" : "");
wr.Write(endVarName != null ? $"{endVarName} < {loopIndex.GetOrCreateCompileName(currentIdGenerator)}" : "");
bodyWr = wr.NewBlock($"; )");
bodyWr.WriteLine($"{loopIndex.CompileName}--;");
bodyWr.WriteLine($"{loopIndex.GetOrCreateCompileName(currentIdGenerator)}--;");
}
bodyWr = EmitContinueLabel(labels, bodyWr);
TrStmtList(body, bodyWr);
Expand Down
8 changes: 4 additions & 4 deletions Source/DafnyCore/Backends/CSharp/CsharpSynthesizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public ConcreteSyntaxTree SynthesizeMethod(Method method,
o => codeGenerator.idGenerator.FreshId(o.CompileName + "Return"));
foreach (var (obj, returnName) in objectToReturnName) {
parameterString = Regex.Replace(parameterString,
$"(^|[^a-zA-Z0-9_]){obj.CompileName}([^a-zA-Z0-9_]|$)",
$"(^|[^a-zA-Z0-9_]){obj.GetOrCreateCompileName(codeGenerator.currentIdGenerator)}([^a-zA-Z0-9_]|$)",
"$1" + returnName + "$2");
}
wr.FormatLine($"{keywords}{returnType} {codeGenerator.PublicIdProtect(method.GetCompileName(Options))}{typeParameters}({parameterString}) {{");
Expand All @@ -110,7 +110,7 @@ public ConcreteSyntaxTree SynthesizeMethod(Method method,
wr.FormatLine($"var {mockName} = new Mock<{typeName}>();");
wr.FormatLine($"{mockName}.CallBase = true;");
}
wr.FormatLine($"var {obj.CompileName} = {mockName}.Object;");
wr.FormatLine($"var {obj.GetOrCreateCompileName(method.CodeGenIdGenerator)} = {mockName}.Object;");
}

// Stub methods and fields according to the Dafny post-conditions:
Expand Down Expand Up @@ -244,7 +244,7 @@ private void SynthesizeExpression(ConcreteSyntaxTree wr, BinaryExpr binaryExpr,
var typeName = codeGenerator.TypeName(arg.Type, wr, arg.tok);
var bound = GetBound(arg);
if (bound != null) {
wr.Format($"{typeName} {bound.Item1.CompileName}");
wr.Format($"{typeName} {bound.Item1.GetOrCreateCompileName(codeGenerator.currentIdGenerator)}");
} else {
// if the argument is not a bound variable, it is irrelevant to the
// expression in the lambda
Expand Down Expand Up @@ -274,7 +274,7 @@ private void SynthesizeExpression(ConcreteSyntaxTree wr, ForallExpr forallExpr,
var boundVar = forallExpr.BoundVars[i];
var varType = codeGenerator.TypeName(boundVar.Type, wr, boundVar.tok);
bounds[boundVar] = $"It.Is<{varType}>(x => {matcherName}.Match(x))";
declarations.Add($"var {boundVar.CompileName} = ({varType}) {tmpId}[{i}];");
declarations.Add($"var {boundVar.GetOrCreateCompileName(codeGenerator.currentIdGenerator)} = ({varType}) {tmpId}[{i}];");
}

wr.WriteLine($"var {matcherName} = new Dafny.MultiMatcher({declarations.Count}, {tmpId} => {{");
Expand Down
4 changes: 2 additions & 2 deletions Source/DafnyCore/Backends/Cplusplus/CppCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -558,12 +558,12 @@ protected override IClassWriter DeclareDatatype(DatatypeDecl dt, ConcreteSyntaxT
for (int i = 0; i < n - 1; i++) {
var ctor_i = dtor.EnclosingCtors[i];
var ctor_name = DatatypeSubStructName(ctor_i);
Contract.Assert(arg.CompileName == dtor.CorrespondingFormals[i].CompileName);
Contract.Assert(arg.GetOrCreateCompileName(currentIdGenerator) == dtor.CorrespondingFormals[i].GetOrCreateCompileName(currentIdGenerator));
wDtor.WriteLine("if (is_{0}()) {{ return std::get<{0}{1}>(v).{2}; }}",
ctor_name, InstantiateTemplate(dt.TypeArgs), IdName(arg));
}

Contract.Assert(arg.CompileName == dtor.CorrespondingFormals[n - 1].CompileName);
Contract.Assert(arg.GetOrCreateCompileName(currentIdGenerator) == dtor.CorrespondingFormals[n - 1].GetOrCreateCompileName(currentIdGenerator));
var final_ctor_name = DatatypeSubStructName(dtor.EnclosingCtors[n - 1], true);
wDtor.WriteLine("return std::get<{0}>(v).{1}; ",
final_ctor_name, IdName(arg));
Expand Down
Loading