void StatementRegions(Statement stmt, List <IdRegion> regions, Microsoft.Dafny.Program prog, ModuleDefinition module) { Contract.Requires(stmt != null); Contract.Requires(regions != null); Contract.Requires(prog != null); IdRegion.AddRecognizedAttributes(stmt.Attributes, regions, prog); if (stmt is VarDeclStmt) { var s = (VarDeclStmt)stmt; // Add the variables here, once, and then go directly to the RHS's (without letting the sub-statements re-do the LHS's) foreach (var local in s.Locals) { IdRegion.AddRecognizedAttributes(local.Attributes, regions, prog); IdRegion.Add(regions, prog, local.Tok, local, true, (ICallable)null, module); } if (s.Update == null) { // the VarDeclStmt has no associated assignment } else if (s.Update is UpdateStmt) { var upd = (UpdateStmt)s.Update; foreach (var rhs in upd.Rhss) { foreach (var ee in rhs.SubExpressions) { ExprRegions(ee, regions, prog, module); } if (rhs is TypeRhs) { CallStmt call = ((TypeRhs)rhs).InitCall; if (call != null) { var method = call.Method; if (method != null) { if (method is Constructor) { // call token starts at the beginning of "new C()", so we need to add 4 to the length. RecordUseAndDef(prog, call.Tok, method.EnclosingClass.Name.Length + 4, method.EnclosingClass.tok); } else { RecordUseAndDef(prog, call.Tok, method.Name.Length, method.tok); } } } } } } else { var upd = (AssignSuchThatStmt)s.Update; ExprRegions(upd.Expr, regions, prog, module); } // we're done, so don't do the sub-statements/expressions again return; } else if (stmt is LetStmt) { var s = (LetStmt)stmt; foreach (var local in s.LHS.Vars) { IdRegion.Add(regions, prog, local.Tok, local, true, (ICallable)null, module); } } else if (stmt is ForallStmt) { var s = (ForallStmt)stmt; s.BoundVars.ForEach(bv => IdRegion.Add(regions, prog, bv.tok, bv, true, (ICallable)null, module)); } else if (stmt is MatchStmt) { var s = (MatchStmt)stmt; foreach (var kase in s.Cases) { kase.Arguments.ForEach(bv => { IdRegion.Add(regions, prog, bv.tok, bv, true, (ICallable)null, module); // if the arguments is an encapsulation of different boundvars from nested match cases, // add the boundvars so that they can show up in the IDE correctly if (bv.tok is MatchCaseToken) { MatchCaseToken mt = (MatchCaseToken)bv.tok; foreach (Tuple <Bpl.IToken, BoundVar, bool> entry in mt.varList) { IdRegion.Add(regions, prog, entry.Item1, entry.Item2, entry.Item3, (ICallable)null, module); } } }); } } else if (stmt is LoopStmt) { var s = (LoopStmt)stmt; if (s.Mod.Expressions != null) { s.Mod.Expressions.ForEach(fe => FrameExprRegions(fe, regions, false, prog, module)); } } else if (stmt is CalcStmt) { var s = (CalcStmt)stmt; // skip the last line, which is just a duplicate anyway for (int i = 0; i < s.Lines.Count - 1; i++) { ExprRegions(s.Lines[i], regions, prog, module); } foreach (var ss in stmt.SubStatements) { StatementRegions(ss, regions, prog, module); } return; } else if (stmt is CallStmt) { var s = (CallStmt)stmt; var method = s.Method; if (method != null) { RecordUseAndDef(prog, s.MethodSelect.tok, method.Name.Length, method.tok); } } foreach (var ee in stmt.SubExpressions) { ExprRegions(ee, regions, prog, module); } foreach (var ss in stmt.SubStatements) { StatementRegions(ss, regions, prog, module); } }
void ExprRegions(Microsoft.Dafny.Expression expr, List <IdRegion> regions, Microsoft.Dafny.Program prog, ModuleDefinition module) { Contract.Requires(expr != null); Contract.Requires(regions != null); Contract.Requires(prog != null); if (expr is AutoGeneratedExpression) { // do nothing return; } else if (expr is IdentifierExpr) { var e = (IdentifierExpr)expr; IdRegion.Add(regions, prog, e.tok, e.Var, false, (ICallable)null, module); } else if (expr is MemberSelectExpr) { var e = (MemberSelectExpr)expr; var field = e.Member as Field; if (field != null) { var kind = !(field is ConstantField) ? "field" : field.IsStatic && !(field.EnclosingClass is DefaultClassDecl) ? "static const" : "const"; IdRegion.Add(regions, prog, e.tok, field, e.Type, kind, false, module); } if (e.Member != null) { RecordUseAndDef(prog, e.tok, e.Member.Name.Length, e.Member.tok); } } else if (expr is FunctionCallExpr) { var e = (FunctionCallExpr)expr; var func = e.Function; if (func != null) { RecordUseAndDef(prog, e.tok, func.Name.Length, func.tok); } } else if (expr is ApplySuffix) { // No need to call ExprRegions on the Lhs field because the for loop at the end of this function will do that. } else if (expr is LetExpr) { var e = (LetExpr)expr; IdRegion.AddRecognizedAttributes(e.Attributes, regions, prog); foreach (var bv in e.BoundVars) { IdRegion.Add(regions, prog, bv.tok, bv, true, (ICallable)null, module); } } else if (expr is ComprehensionExpr) { var e = (ComprehensionExpr)expr; IdRegion.AddRecognizedAttributes(e.Attributes, regions, prog); foreach (var bv in e.BoundVars) { IdRegion.Add(regions, prog, bv.tok, bv, true, (ICallable)null, module); } if (expr is QuantifierExpr) { // If the quantifier has a SplitQuantifier, then its .SubExpressions routine goes over each split. // That's not what we want here, because it would cause duplicated hover texts. Instead, we just // do what a QuantifierExpr would do without a SplitQuantifier, which is as follows: foreach (var ee in Attributes.SubExpressions(e.Attributes)) { ExprRegions(ee, regions, prog, module); } if (e.Range != null) { ExprRegions(e.Range, regions, prog, module); } ExprRegions(e.Term, regions, prog, module); return; } } else if (expr is MatchExpr) { var e = (MatchExpr)expr; foreach (var kase in e.Cases) { kase.Arguments.ForEach(bv => { IdRegion.Add(regions, prog, bv.tok, bv, true, (ICallable)null, module); // if the arguments is an encapsulation of different boundvars from nested match cases, // add the boundvars so that they can show up in the IDE correctly if (bv.tok is MatchCaseToken) { MatchCaseToken mt = (MatchCaseToken)bv.tok; foreach (Tuple <Bpl.IToken, BoundVar, bool> entry in mt.varList) { IdRegion.Add(regions, prog, entry.Item1, entry.Item2, entry.Item3, (ICallable)null, module); } } }); } } else if (expr is ChainingExpression) { var e = (ChainingExpression)expr; // Do the subexpressions only once (that is, avoid the duplication that occurs in the desugared form of the ChainingExpression) e.Operands.ForEach(ee => ExprRegions(ee, regions, prog, module)); return; // return here, so as to avoid doing the subexpressions below } foreach (var ee in expr.SubExpressions) { ExprRegions(ee, regions, prog, module); } }
static void ExprRegions(Microsoft.Dafny.Expression expr, List <IdRegion> regions, Microsoft.Dafny.Program prog, ModuleDefinition module) { Contract.Requires(expr != null); Contract.Requires(regions != null); Contract.Requires(prog != null); if (expr is AutoGeneratedExpression) { // do nothing return; } else if (expr is IdentifierExpr) { var e = (IdentifierExpr)expr; IdRegion.Add(regions, prog, e.tok, e.Var, false, module); } else if (expr is MemberSelectExpr) { var e = (MemberSelectExpr)expr; var field = e.Member as Field; if (field != null) { IdRegion.Add(regions, prog, e.tok, field, e.Type, "field", false, module); } } else if (expr is LetExpr) { var e = (LetExpr)expr; IdRegion.AddRecognizedAttributes(e.Attributes, regions, prog); foreach (var bv in e.BoundVars) { IdRegion.Add(regions, prog, bv.tok, bv, true, module); } } else if (expr is ComprehensionExpr) { var e = (ComprehensionExpr)expr; IdRegion.AddRecognizedAttributes(e.Attributes, regions, prog); foreach (var bv in e.BoundVars) { IdRegion.Add(regions, prog, bv.tok, bv, true, module); } } else if (expr is MatchExpr) { var e = (MatchExpr)expr; foreach (var kase in e.Cases) { kase.Arguments.ForEach(bv => { IdRegion.Add(regions, prog, bv.tok, bv, true, module); // if the arguments is an encapsulation of different boundvars from nested match cases, // add the boundvars so that they can show up in the IDE correctly if (bv.tok is MatchCaseToken) { MatchCaseToken mt = (MatchCaseToken)bv.tok; foreach (Tuple <Bpl.IToken, BoundVar, bool> entry in mt.varList) { IdRegion.Add(regions, prog, entry.Item1, entry.Item2, entry.Item3, module); } } }); } } else if (expr is ChainingExpression) { var e = (ChainingExpression)expr; // Do the subexpressions only once (that is, avoid the duplication that occurs in the desugared form of the ChainingExpression) e.Operands.ForEach(ee => ExprRegions(ee, regions, prog, module)); return; // return here, so as to avoid doing the subexpressions below } foreach (var ee in expr.SubExpressions) { ExprRegions(ee, regions, prog, module); } }
bool ComputeIdentifierRegions(Microsoft.Dafny.Program program, ITextSnapshot snapshot) { Contract.Requires(snapshot != null); if (program == _program) { return(false); // no new regions } _snapshot = snapshot; List <IdRegion> newRegions = new List <IdRegion>(); foreach (var info in program.reporter.AllMessages[ErrorLevel.Info]) { IdRegion.Add(newRegions, program, info.token, info.message, info.token.val.Length); } foreach (var module in program.Modules()) { if (module.IsFacade) { continue; } foreach (var d in module.TopLevelDecls) { if (d is IteratorDecl) { // iterators already get a hover text that shows the class desugaring, so that hover text shows the type parameters } else if (d is OpaqueTypeDecl) { IdRegion.Add(newRegions, program, d.tok, string.Format("{0} {1}{2}", d.WhatKind, d.Name, Printer.TPCharacteristicsSuffix(((OpaqueTypeDecl)d).Characteristics)), d.TypeArgs); } else if (d is TypeSynonymDecl) // also covers SubsetTypeDecl { IdRegion.Add(newRegions, program, d.tok, string.Format("{0} {1}{2}", d.WhatKind, d.Name, Printer.TPCharacteristicsSuffix(((TypeSynonymDecl)d).Characteristics)), d.TypeArgs); } else { IdRegion.Add(newRegions, program, d.tok, string.Format("{0} {1}", d.WhatKind, d.Name), d.TypeArgs); } IdRegion.AddRecognizedAttributes(d.Attributes, newRegions, program); if (d is DatatypeDecl) { var dt = (DatatypeDecl)d; foreach (var ctor in dt.Ctors) { foreach (var dtor in ctor.Destructors) { var i = dtor.EnclosingCtors.IndexOf(ctor); var formal = dtor.CorrespondingFormals[i]; if (formal.HasName) { IdRegion.Add(newRegions, program, formal.tok, dtor, null, "destructor", true, module); } } } } else if (d is IteratorDecl) { var iter = (IteratorDecl)d; foreach (var p in iter.Ins) { IdRegion.Add(newRegions, program, p.tok, p, true, iter, module); } foreach (var p in iter.Outs) { IdRegion.Add(newRegions, program, p.tok, p, true, "yield-parameter", iter, module); } iter.Reads.Expressions.ForEach(fe => FrameExprRegions(fe, newRegions, true, program, module)); iter.Modifies.Expressions.ForEach(fe => FrameExprRegions(fe, newRegions, true, program, module)); iter.Requires.ForEach(e => ExprRegions(e.E, newRegions, program, module)); iter.YieldRequires.ForEach(e => ExprRegions(e.E, newRegions, program, module)); iter.YieldEnsures.ForEach(e => ExprRegions(e.E, newRegions, program, module)); iter.Ensures.ForEach(e => ExprRegions(e.E, newRegions, program, module)); if (!((ICallable)iter).InferredDecreases) { iter.Decreases.Expressions.ForEach(e => ExprRegions(e, newRegions, program, module)); } if (iter.Body != null) { StatementRegions(iter.Body, newRegions, program, module); } } else if (d is ClassDecl) { var cl = (ClassDecl)d; foreach (var member in cl.Members) { IdRegion.AddRecognizedAttributes(member.Attributes, newRegions, program); if (Attributes.Contains(member.Attributes, "auto_generated")) { // do nothing } else if (member is Function) { var f = (Function)member; var kind = f.WhatKind; var name = f.Name; if (!(f.EnclosingClass is DefaultClassDecl)) { if (f.IsStatic) { kind = "static " + kind; } name = f.EnclosingClass.Name + "." + name; } IdRegion.Add(newRegions, program, f.tok, string.Format("{0} {1}", kind, name), f.TypeArgs); foreach (var p in f.Formals) { IdRegion.Add(newRegions, program, p.tok, p, true, f, module); } if (f.Result != null) { IdRegion.Add(newRegions, program, f.Result.tok, f.Result, true, f, module); } f.Req.ForEach(e => ExprRegions(e.E, newRegions, program, module)); f.Reads.ForEach(fe => FrameExprRegions(fe, newRegions, true, program, module)); f.Ens.ForEach(e => ExprRegions(e.E, newRegions, program, module)); f.Decreases.Expressions.ForEach(e => ExprRegions(e, newRegions, program, module)); if (f.Body != null) { ExprRegions(f.Body, newRegions, program, module); } } else if (member is Method) { var m = (Method)member; var kind = m.WhatKind; var name = m.Name; if (!(m.EnclosingClass is DefaultClassDecl)) { if (m.IsStatic) { kind = "static " + kind; } name = m.EnclosingClass.Name + "." + name; } IdRegion.Add(newRegions, program, m.tok, string.Format("{0} {1}", kind, name), m.TypeArgs); foreach (var p in m.Ins) { IdRegion.Add(newRegions, program, p.tok, p, true, m, module); } foreach (var p in m.Outs) { IdRegion.Add(newRegions, program, p.tok, p, true, m, module); } m.Req.ForEach(e => ExprRegions(e.E, newRegions, program, module)); m.Mod.Expressions.ForEach(fe => FrameExprRegions(fe, newRegions, true, program, module)); m.Ens.ForEach(e => ExprRegions(e.E, newRegions, program, module)); m.Decreases.Expressions.ForEach(e => ExprRegions(e, newRegions, program, module)); if (m.Body != null) { StatementRegions(m.Body, newRegions, program, module); } } else if (member is ConstantField) { var cf = (ConstantField)member; IdRegion.Add(newRegions, program, cf.tok, cf, null, cf.IsStatic && !(cf.EnclosingClass is DefaultClassDecl) ? "static const" : "const", true, module); if (cf.Rhs != null) { ExprRegions(cf.Rhs, newRegions, program, module); } } else if (member is SpecialField) { // do nothing } else if (member is Field) { var fld = (Field)member; IdRegion.Add(newRegions, program, fld.tok, fld, null, "field", true, module); } } } else if (d is NewtypeDecl) { var dd = (NewtypeDecl)d; if (dd.Var != null) { IdRegion.Add(newRegions, program, dd.Var.tok, dd.Var, true, (ICallable)null, module); ExprRegions(dd.Constraint, newRegions, program, module); } } else if (d is SubsetTypeDecl) { var dd = (SubsetTypeDecl)d; if (dd.Var != null) { IdRegion.Add(newRegions, program, dd.Var.tok, dd.Var, true, (ICallable)null, module); ExprRegions(dd.Constraint, newRegions, program, module); } } } } _regions = newRegions; _program = program; return(true); }
bool ComputeIdentifierRegions(Microsoft.Dafny.Program program, ITextSnapshot snapshot) { Contract.Requires(snapshot != null); if (program == _program) { return(false); // no new regions } List <IdRegion> newRegions = new List <IdRegion>(); foreach (var info in program.reporter.AllMessages[ErrorLevel.Info]) { IdRegion.Add(newRegions, program, info.token, info.message, info.token.val.Length); } foreach (var module in program.Modules) { if (module.IsFacade) { continue; } foreach (var d in module.TopLevelDecls) { IdRegion.AddRecognizedAttributes(d.Attributes, newRegions, program); if (d is DatatypeDecl) { var dt = (DatatypeDecl)d; foreach (var ctor in dt.Ctors) { foreach (var dtor in ctor.Destructors) { if (dtor.CorrespondingFormal.HasName) { IdRegion.Add(newRegions, program, dtor.tok, dtor, null, "destructor", true, module); } } } } else if (d is IteratorDecl) { var iter = (IteratorDecl)d; foreach (var p in iter.Ins) { IdRegion.Add(newRegions, program, p.tok, p, true, module); } foreach (var p in iter.Outs) { IdRegion.Add(newRegions, program, p.tok, p, true, "yield-parameter", module); } iter.Reads.Expressions.ForEach(fe => FrameExprRegions(fe, newRegions, true, program, module)); iter.Modifies.Expressions.ForEach(fe => FrameExprRegions(fe, newRegions, true, program, module)); iter.Requires.ForEach(e => ExprRegions(e.E, newRegions, program, module)); iter.YieldRequires.ForEach(e => ExprRegions(e.E, newRegions, program, module)); iter.YieldEnsures.ForEach(e => ExprRegions(e.E, newRegions, program, module)); iter.Ensures.ForEach(e => ExprRegions(e.E, newRegions, program, module)); if (!((ICallable)iter).InferredDecreases) { iter.Decreases.Expressions.ForEach(e => ExprRegions(e, newRegions, program, module)); } if (iter.Body != null) { StatementRegions(iter.Body, newRegions, program, module); } } else if (d is ClassDecl) { var cl = (ClassDecl)d; foreach (var member in cl.Members) { IdRegion.AddRecognizedAttributes(member.Attributes, newRegions, program); if (Attributes.Contains(member.Attributes, "auto_generated")) { // do nothing } else if (member is Function) { var f = (Function)member; foreach (var p in f.Formals) { IdRegion.Add(newRegions, program, p.tok, p, true, module); } f.Req.ForEach(e => ExprRegions(e, newRegions, program, module)); f.Reads.ForEach(fe => FrameExprRegions(fe, newRegions, true, program, module)); f.Ens.ForEach(e => ExprRegions(e, newRegions, program, module)); f.Decreases.Expressions.ForEach(e => ExprRegions(e, newRegions, program, module)); if (f.Body != null) { ExprRegions(f.Body, newRegions, program, module); } } else if (member is Method) { var m = (Method)member; foreach (var p in m.Ins) { IdRegion.Add(newRegions, program, p.tok, p, true, module); } foreach (var p in m.Outs) { IdRegion.Add(newRegions, program, p.tok, p, true, module); } m.Req.ForEach(e => ExprRegions(e.E, newRegions, program, module)); m.Mod.Expressions.ForEach(fe => FrameExprRegions(fe, newRegions, true, program, module)); m.Ens.ForEach(e => ExprRegions(e.E, newRegions, program, module)); m.Decreases.Expressions.ForEach(e => ExprRegions(e, newRegions, program, module)); if (m.Body != null) { StatementRegions(m.Body, newRegions, program, module); } } else if (member is SpecialField) { // do nothing } else if (member is Field) { var fld = (Field)member; IdRegion.Add(newRegions, program, fld.tok, fld, null, "field", true, module); } } } else if (d is NewtypeDecl) { var dd = (NewtypeDecl)d; if (dd.Var != null) { IdRegion.Add(newRegions, program, dd.Var.tok, dd.Var, true, module); ExprRegions(dd.Constraint, newRegions, program, module); } } } } _snapshot = snapshot; _regions = newRegions; _program = program; return(true); }