Skip to content

Commit 6cb2961

Browse files
authored
Merge pull request #804 from viperproject/sem-highlight
Add information required for LSP features to Parse AST
2 parents 635e18e + 37f2919 commit 6cb2961

6 files changed

Lines changed: 35 additions & 23 deletions

File tree

silver

Submodule silver updated 75 files

src/main/scala/extensions/TryBlockParserPlugin.scala

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,13 @@ import viper.silver.plugin.{ParserPluginTemplate, SilverPlugin}
1111

1212
class TryBlockParserPlugin(fp: FastParser) extends SilverPlugin with ParserPluginTemplate {
1313
import fastparse._
14-
import viper.silver.parser.FastParserCompanion.whitespace
15-
import fp.{FP, block, ParserExtension}
14+
import viper.silver.parser.FastParserCompanion.{PositionParsing, reservedKw, whitespace}
15+
import fp.{ParserExtension, lineCol, _file, stmtBlock}
1616

17-
18-
private val tryKeyword = "try"
19-
20-
def tryBlock[_:P]: P[PTryBlock] =FP("try" ~/ block) map { case (pos, s) => PTryBlock(s)(pos) }
17+
def tryBlock[$: P]: P[PTryBlock] = P((P(PTryKeyword) ~ stmtBlock()) map (PTryBlock.apply _).tupled).pos
2118

2219
override def beforeParse(input: String, isImported: Boolean): String = {
23-
ParserExtension.addNewKeywords(Set(tryKeyword))
20+
ParserExtension.addNewKeywords(Set(PTryKeyword))
2421
ParserExtension.addNewStmtAtEnd(tryBlock(_))
2522

2623
input

src/main/scala/extensions/TryBlockStmt.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ package viper.silicon.extensions
88

99
import viper.silver.ast._
1010
import viper.silver.ast.pretty.PrettyPrintPrimitives
11-
import viper.silver.parser.{NameAnalyser, PExtender, PNode, PStmt, Translator, TypeChecker}
11+
import viper.silver.parser.{NameAnalyser, PExtender, PStmt, Translator, TypeChecker, PKw, PKeywordStmt, PReserved}
1212

13-
final case class PTryBlock(body: PStmt)(val pos: (Position, Position) = (NoPosition, NoPosition)) extends PExtender with PStmt {
14-
override val getSubnodes: Seq[PNode] = Seq(body)
13+
/** Keyword used to define `try` statement. */
14+
case object PTryKeyword extends PKw("try") with PKeywordStmt
15+
16+
final case class PTryBlock(kw: PReserved[PTryKeyword.type], body: PStmt)(val pos: (Position, Position) = (NoPosition, NoPosition)) extends PExtender with PStmt {
1517

1618
override def translateStmt(translator: Translator): Stmt = {
1719
TryBlock(translator.stmt(body))(translator.liftPos(this))

src/main/scala/rules/Evaluator.scala

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -678,8 +678,21 @@ object evaluator extends EvaluationRules {
678678

679679
val body = eQuant.exp
680680
// Remove whitespace in identifiers to avoid parsing problems for the axiom profiler.
681-
val posString = viper.silicon.utils.ast.sourceLine(sourceQuant).replaceAll(" ", "")
682-
val name = s"prog.l$posString"
681+
// TODO: add flag to enable old behavior for AxiomProfiler
682+
val fallbackName = "l" + viper.silicon.utils.ast.sourceLine(sourceQuant).replaceAll(" ", "")
683+
val posString = if (!sourceQuant.pos.isInstanceOf[ast.AbstractSourcePosition]) {
684+
fallbackName
685+
} else {
686+
val pos = sourceQuant.pos.asInstanceOf[ast.AbstractSourcePosition]
687+
if (pos.end.isEmpty) {
688+
fallbackName
689+
} else {
690+
val file = pos.file.toString()
691+
val end = pos.end.get
692+
s"$file@${pos.start.line}@${pos.start.column}@${end.line}@${end.column}"
693+
}
694+
}
695+
val name = s"prog.$posString"
683696
evalQuantified(s, qantOp, eQuant.variables, Nil, Seq(body), Some(eTriggers), name, pve, v){
684697
case (s1, tVars, _, Seq(tBody), tTriggers, (tAuxGlobal, tAux), v1) =>
685698
val tAuxHeapIndep = tAux.flatMap(v.quantifierSupporter.makeTriggersHeapIndependent(_, v1.decider.fresh))

src/main/scala/verifier/DefaultMainVerifier.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,13 +172,13 @@ class DefaultMainVerifier(config: Config,
172172
val res = viper.silicon.utils.ast.autoTrigger(forall, forall.autoTrigger)
173173
if (res.triggers.isEmpty)
174174
reporter.report(WarningsDuringVerification(Seq(VerifierWarning("No triggers provided or inferred for quantifier.", res.pos))))
175-
reporter report QuantifierChosenTriggersMessage(res, res.triggers)
175+
reporter report QuantifierChosenTriggersMessage(res, res.triggers, forall.triggers)
176176
res
177177
case exists: ast.Exists =>
178178
val res = viper.silicon.utils.ast.autoTrigger(exists, exists.autoTrigger)
179179
if (res.triggers.isEmpty)
180180
reporter.report(WarningsDuringVerification(Seq(VerifierWarning("No triggers provided or inferred for quantifier.", res.pos))))
181-
reporter report QuantifierChosenTriggersMessage(res, res.triggers)
181+
reporter report QuantifierChosenTriggersMessage(res, res.triggers, exists.triggers)
182182
res
183183
}, Traverse.BottomUp)
184184

src/test/scala/CounterexampleTests.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import viper.silicon.interfaces.SiliconMappedCounterexample
1313
import viper.silicon.reporting.{ExtractedModel, ExtractedModelEntry, LitIntEntry, LitPermEntry, NullRefEntry, RecursiveRefEntry, RefEntry, SeqEntry}
1414
import viper.silicon.state.terms.Rational
1515
import viper.silver.parser.FastParserCompanion.whitespace
16-
import viper.silver.parser.{FastParser, PAccPred, PBinExp, PExp, PFieldAccess, PIdnUse, PIntLit, PLookup, PUnExp}
16+
import viper.silver.parser.{FastParser, PAccPred, PBinExp, PExp, PFieldAccess, PIdnUse, PIntLit, PLookup, PUnExp, PSymOp}
1717
import viper.silver.verifier.{FailureContext, VerificationError}
1818

1919
import java.nio.file.Path
@@ -112,7 +112,7 @@ case class ExpectedCounterexampleAnnotation(id: OutputAnnotationId, file: Path,
112112
def meetsExpectations(model1: ExpectedCounterexample, model2: ExtractedModel): Boolean = {
113113
model1.exprs.forall {
114114
case accPred: PAccPred => containsAccessPredicate(accPred, model2)
115-
case PBinExp(lhs, "==", rhs) => containsEquality(lhs, rhs, model2)
115+
case PBinExp(lhs, r, rhs) if r.rs == PSymOp.EqEq => containsEquality(lhs, rhs, model2)
116116
}
117117
}
118118

@@ -130,13 +130,13 @@ case class ExpectedCounterexampleAnnotation(id: OutputAnnotationId, file: Path,
130130
/** resolves `expr` to a model entry in the given model. In case it's a field access, the corresponding permissions are returned as well */
131131
def resolve(expr: PExp, model: ExtractedModel): Option[(ExtractedModelEntry, Option[Rational])] = expr match {
132132
case PIntLit(value) => Some(LitIntEntry(value), None)
133-
case PUnExp("-", PIntLit(value)) => Some(LitIntEntry(-value), None)
134-
case PBinExp(PIntLit(n), "/", PIntLit(d)) => Some(LitPermEntry(Rational(n, d)), None)
135-
case PIdnUse(name) => model.entries.get(name).map((_, None))
136-
case PFieldAccess(rcv, idnuse) => resolveWoPerm(rcv, model).flatMap {
133+
case PUnExp(r, PIntLit(value)) if r.rs == PSymOp.Neg => Some(LitIntEntry(-value), None)
134+
case PBinExp(PIntLit(n), r, PIntLit(d)) if r.rs == PSymOp.Div => Some(LitPermEntry(Rational(n, d)), None)
135+
case idnuse: PIdnUse => model.entries.get(idnuse.name).map((_, None))
136+
case PFieldAccess(rcv, _, idnuse) => resolveWoPerm(rcv, model).flatMap {
137137
case RefEntry(_, fields) => fields.get(idnuse.name)
138138
}
139-
case PLookup(base, idx) => resolveWoPerm(Vector(base, idx), model).flatMap {
139+
case PLookup(base, _, idx, _) => resolveWoPerm(Vector(base, idx), model).flatMap {
140140
case Vector(SeqEntry(_, values), LitIntEntry(evaluatedIdx)) if values.size > evaluatedIdx => Some(values(evaluatedIdx.toInt), None)
141141
}
142142
}
@@ -184,7 +184,7 @@ class CounterexampleParser(fp: FastParser) {
184184
case class ExpectedCounterexample(exprs: Seq[PExp]) {
185185
assert(exprs.forall {
186186
case _: PAccPred => true
187-
case PBinExp(_, "==", _) => true
187+
case PBinExp(_, r, _) if r.rs == PSymOp.EqEq => true
188188
case _ => false
189189
})
190190
}

0 commit comments

Comments
 (0)