Skip to content

Commit 20485bf

Browse files
committed
Revert "Merge pull request #201 from viperproject/sem-highlight"
This reverts commit 7c5305b, reversing changes made to 5cd18bd.
1 parent 003ecdb commit 20485bf

43 files changed

Lines changed: 590 additions & 3741 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,3 @@ ter.bat
88
ver.bat
99
.bsp/
1010
logs/
11-
.bloop
12-
.metals
13-
metals.sbt

build.sbt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ lazy val server = (project in file("."))
1818
// General settings
1919
name := "ViperServer",
2020
organization := "viper",
21-
version := "3.0.0", // has to be a proper semver
21+
version := "2.0.0", // has to be a proper semver
2222

2323
// Fork test to a different JVM than SBT's, avoiding SBT's classpath interfering with
2424
// classpath used by Scala's reflection.
@@ -30,7 +30,7 @@ lazy val server = (project in file("."))
3030
libraryDependencies += "com.typesafe.akka" %% "akka-stream" % "2.6.10",
3131
libraryDependencies += "com.typesafe.akka" %% "akka-stream-testkit" % "2.6.10" % Test,
3232
libraryDependencies += "com.typesafe.akka" %% "akka-http-testkit" % "10.2.1" % Test,
33-
libraryDependencies += "org.eclipse.lsp4j" % "org.eclipse.lsp4j" % "0.20.1", // Java implementation of language server protocol
33+
libraryDependencies += "org.eclipse.lsp4j" % "org.eclipse.lsp4j" % "0.15.0", // Java implementation of language server protocol
3434

3535
silicon / excludeFilter := "logback.xml", /* Ignore Silicon's Logback configuration */
3636
carbon / excludeFilter := "logback.xml", /* Ignore Carbon's Logback configuration */

src/main/scala/viper/server/core/AstWorker.scala

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import viper.server.ViperConfig
1111
import viper.server.utility.AstGenerator
1212
import viper.server.vsi.AstConstructionException
1313
import viper.silver.ast.Program
14-
import viper.silver.ast.utility.FileLoader
1514
import viper.silver.reporter.{Entity, ExceptionReport}
1615
import viper.silver.verifier.VerificationResult
1716

@@ -27,8 +26,7 @@ case class ServerCrashException(e: Throwable) extends Exception(e)
2726

2827
class AstWorker(val arg_list: List[String],
2928
override val logger: Logger,
30-
private val config: ViperConfig,
31-
private val loader: Option[FileLoader]
29+
private val config: ViperConfig
3230
)(override val executor: VerificationExecutionContext)
3331
extends MessageReportingTask[Option[Program]] {
3432

@@ -39,7 +37,7 @@ class AstWorker(val arg_list: List[String],
3937
val astGen = new AstGenerator(logger, reporter, arg_list, disablePlugins = config.disablePlugins())
4038

4139
val ast_option: Option[Program] = try {
42-
astGen.generateViperAst(file, loader)
40+
astGen.generateViperAst(file)
4341
} catch {
4442
case _: java.nio.file.NoSuchFileException =>
4543
logger.error(s"The file ($file) for which verification has been requested was not found.")

src/main/scala/viper/server/core/ViperCoreServer.scala

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import ch.qos.logback.classic.Logger
1313
import viper.server.ViperConfig
1414
import viper.server.vsi.{AstHandle, AstJobId, VerJobId, VerificationServer}
1515
import viper.silver.ast.Program
16-
import viper.silver.ast.utility.FileLoader
1716
import viper.silver.logger.ViperLogger
1817

1918
import scala.concurrent.duration._
@@ -59,10 +58,10 @@ abstract class ViperCoreServer(val config: ViperConfig)(implicit val executor: V
5958
}
6059
}
6160

62-
def requestAst(arg_list: List[String], localLogger: Option[Logger] = None, loader: Option[FileLoader] = None): AstJobId = {
61+
def requestAst(arg_list: List[String], localLogger: Option[Logger] = None): AstJobId = {
6362
require(config != null)
6463
val logger = combineLoggers(localLogger)
65-
val task_backend = new AstWorker(arg_list, logger, config, loader)(executor)
64+
val task_backend = new AstWorker(arg_list, logger, config)(executor)
6665
val ast_id = initializeAstConstruction(task_backend)
6766

6867
if (ast_id.id >= 0) {
@@ -73,7 +72,6 @@ abstract class ViperCoreServer(val config: ViperConfig)(implicit val executor: V
7372
}
7473
ast_id
7574
}
76-
def discardAstJobOnCompletion(jid: AstJobId, jobActor: ActorRef): Unit = discardAstOnCompletion(jid, jobActor)
7775

7876
def verifyWithAstJob(programId: String, ast_id: AstJobId, backend_config: ViperBackendConfig, localLogger: Option[Logger] = None): VerJobId = {
7977
val logger = combineLoggers(localLogger)
@@ -125,11 +123,7 @@ abstract class ViperCoreServer(val config: ViperConfig)(implicit val executor: V
125123
ver_id
126124
}
127125

128-
override def streamMessages(jid: VerJobId, clientActor: ActorRef, full: Boolean): Option[Future[Done]] = {
129-
globalLogger.info(s"Streaming results for job #${jid.id}.")
130-
super.streamMessages(jid, clientActor, full)
131-
}
132-
override def streamMessages(jid: AstJobId, clientActor: ActorRef): Option[Future[Done]] = {
126+
override def streamMessages(jid: VerJobId, clientActor: ActorRef): Option[Future[Done]] = {
133127
globalLogger.info(s"Streaming results for job #${jid.id}.")
134128
super.streamMessages(jid, clientActor)
135129
}

src/main/scala/viper/server/core/ViperCoreServerUtils.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ object ViperCoreServerUtils {
5656
import scala.language.postfixOps
5757

5858
val actor = executor.actorSystem.actorOf(SeqActor.props(jid, core.globalLogger))
59-
val complete_future = core.streamMessages(jid, actor, true).getOrElse(Future.failed(JobNotFoundException))
59+
val complete_future = core.streamMessages(jid, actor).getOrElse(Future.failed(JobNotFoundException))
6060
complete_future.flatMap(_ => {
6161
implicit val askTimeout: Timeout = Timeout(core.config.actorCommunicationTimeout() milliseconds)
6262
(actor ? SeqActor.Result).mapTo[Future[List[Message]]].flatten

src/main/scala/viper/server/frontends/http/jsonWriters/ViperIDEProtocol.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -493,8 +493,6 @@ object ViperIDEProtocol extends akka.http.scaladsl.marshallers.sprayjson.SprayJs
493493
case q: QuantifierInstantiationsMessage => q.toJson
494494
case q: QuantifierChosenTriggersMessage => q.toJson
495495
case v: VerificationTerminationMessage => v.toJson
496-
case p: PProgramReport => p.semanticAnalysisSuccess.toJson
497-
case w: WarningsDuringVerification => w.toJson
498496
}))
499497
})
500498

src/main/scala/viper/server/frontends/lsp/ClientCoordinator.scala

Lines changed: 57 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,15 @@
77
package viper.server.frontends.lsp
88

99
import ch.qos.logback.classic.Logger
10-
import org.eclipse.lsp4j.Range
10+
import org.eclipse.lsp4j.DocumentSymbol
1111
import viper.server.core.VerificationExecutionContext
1212
import viper.server.frontends.lsp.VerificationState.Ready
1313

1414
import java.util.concurrent.{ConcurrentHashMap, ConcurrentMap}
15+
import scala.collection.mutable.ArrayBuffer
1516
import scala.concurrent.Future
1617
import scala.jdk.CollectionConverters._
1718
import scala.jdk.FutureConverters._
18-
import viper.server.frontends.lsp.file.FileManager
19-
import viper.server.frontends.lsp.file.VerificationManager
2019

2120
/** manages per-client state and interacts with the server instance (which is shared among all clients) */
2221
class ClientCoordinator(val server: ViperServerService)(implicit executor: VerificationExecutionContext) {
@@ -47,41 +46,59 @@ class ClientCoordinator(val server: ViperServerService)(implicit executor: Verif
4746
!_exited
4847
}
4948

50-
def closeFile(uri: String): Unit = {
51-
val toRemove = Option(_files.get(uri)).map(fm => {
52-
fm.isOpen = false
53-
fm.removeDiagnostics()
54-
fm.isRoot
55-
}).getOrElse(false)
56-
if (toRemove) {
57-
logger.trace(s"Removing FileManager for $uri")
58-
_files.remove(uri)
49+
def addFileIfNecessary(uri: String): Unit = {
50+
logger.trace(s"Adding FileManager for $uri if it does not exist yet")
51+
val coordinator = this
52+
val createFMFunc = new java.util.function.Function[String, FileManager]() {
53+
override def apply(t: String): FileManager = {
54+
logger.trace(s"FileManager created for $uri")
55+
new FileManager(coordinator, uri)
56+
}
5957
}
58+
// we use `computeIfAbsent` instead of `putIfAbsent` such that a new FileManager is only created if it's absent
59+
_files.computeIfAbsent(uri, createFMFunc)
60+
}
61+
62+
def removeFileIfExists(uri: String): Unit = {
63+
logger.trace(s"Removing FileManager for $uri")
64+
_files.remove(uri)
65+
}
66+
67+
/** clears definitions and symbols associated with a file */
68+
def resetFile(uri: String): Unit = {
69+
Option(_files.get(uri))
70+
.foreach(fm => {
71+
fm.symbolInformation = ArrayBuffer.empty
72+
fm.definitions = ArrayBuffer.empty
73+
})
6074
}
6175

6276
def resetDiagnostics(uri: String): Unit = {
63-
getFileManager(uri).removeDiagnostics()
77+
Option(_files.get(uri))
78+
.foreach(fm => fm.resetDiagnostics())
6479
}
6580

66-
def handleChange(uri: String, range: Range, text: String): Unit = {
67-
val fm = getFileManager(uri)
68-
fm.synchronized {
69-
fm.handleContentChange(range, text)
70-
}
81+
def getSymbolsForFile(uri: String): Array[DocumentSymbol]= {
82+
Option(_files.get(uri))
83+
.map(fm => fm.symbolInformation.toArray)
84+
.getOrElse(Array.empty)
85+
}
86+
87+
def getDefinitionsForFile(uri: String): ArrayBuffer[Definition] = {
88+
Option(_files.get(uri))
89+
.map(fm => fm.definitions)
90+
.getOrElse(ArrayBuffer.empty)
7191
}
7292

7393
/** Checks if verification can be started for a given file.
7494
*
7595
* Informs client differently depending on whether or not verification attempt was triggered manually
7696
* */
77-
def canVerificationBeStarted(uri: String, content: String, manuallyTriggered: Boolean): Boolean = {
97+
def canVerificationBeStarted(uri: String, manuallyTriggered: Boolean): Boolean = {
7898
logger.trace("canVerificationBeStarted")
7999
if (server.isRunning) {
80100
logger.trace("server is running")
81-
// This should only be necessary if one wants to verify a closed file for some reason
82-
val fm = getFileManager(uri, Some(content))
83-
// This will be the new project root
84-
makeEmptyRoot(fm)
101+
addFileIfNecessary(uri)
85102
true
86103
} else {
87104
logger.trace("server is not running")
@@ -94,15 +111,16 @@ class ClientCoordinator(val server: ViperServerService)(implicit executor: Verif
94111
}
95112

96113
def stopRunningVerification(uri: String): Future[Boolean] = {
97-
val fm = getFileManager(uri)
98-
fm.stop()
99-
.map(_ => {
100-
logger.trace(s"stopVerification has completed for ${fm.file.uri}")
101-
val params = StateChangeParams(Ready.id, verificationCompleted = 0, verificationNeeded = 0, uri = uri)
102-
sendStateChangeNotification(params, Some(fm))
103-
true
104-
})
105-
.recover(_ => false)
114+
Option(_files.get(uri))
115+
.map(fm => fm.stopVerification()
116+
.map(_ => {
117+
logger.trace(s"stopVerification has completed for ${fm.uri}")
118+
val params = StateChangeParams(Ready.id, verificationCompleted = 0, verificationNeeded = 0, uri = uri)
119+
sendStateChangeNotification(params, Some(fm))
120+
true
121+
})
122+
.recover(_ => false))
123+
.getOrElse(Future.successful(false))
106124
}
107125

108126
/** Stops all running verifications.
@@ -112,26 +130,18 @@ class ClientCoordinator(val server: ViperServerService)(implicit executor: Verif
112130
* */
113131
def stopAllRunningVerifications(): Future[Unit] = {
114132
val tasks = _files.values().asScala.map(fm =>
115-
fm.stop().map(_ => {
116-
logger.trace(s"stopVerification has completed for ${fm.file.uri}")
133+
fm.stopVerification().map(_ => {
134+
logger.trace(s"stopVerification has completed for ${fm.uri}")
117135
}))
118136
Future.sequence(tasks).map(_ => {
119137
logger.debug("all running verifications have been stopped")
120138
})
121139
}
122140

123141
/** returns true if verification was started */
124-
def startVerification(backendClassName: String, customArgs: String, uri: String, manuallyTriggered: Boolean): Future[Boolean] = {
125-
val fm = getFileManager(uri)
126-
fm.startVerification(backendClassName, customArgs, fm.content, manuallyTriggered)
127-
}
128-
129-
/** returns true if parse/typecheck was started */
130-
def startParseTypecheck(uri: String): Boolean = {
131-
val fm = getFileManager(uri)
132-
val project = Option(_files.get(uri)).flatMap(_.projectRoot).getOrElse(uri)
133-
val root = getFileManager(project)
134-
root.runParseTypecheck(fm.content)
142+
def startVerification(backendClassName: String, customArgs: String, uri: String, manuallyTriggered: Boolean): Boolean = {
143+
Option(_files.get(uri))
144+
.exists(fm => fm.startVerification(backendClassName, customArgs, manuallyTriggered))
135145
}
136146

137147
/** flushes verification cache, optionally only for a particular file */
@@ -163,9 +173,9 @@ class ClientCoordinator(val server: ViperServerService)(implicit executor: Verif
163173
*
164174
* If state change is related to a particular file, its manager's state is also updated.
165175
* */
166-
def sendStateChangeNotification(params: StateChangeParams, task: Option[VerificationManager]): Unit = {
176+
def sendStateChangeNotification(params: StateChangeParams, task: Option[FileManager]): Unit = {
167177
// update file manager's state:
168-
task.foreach(vm => vm.state = VerificationState(params.newState))
178+
task.foreach(fm => fm.state = VerificationState(params.newState))
169179
try {
170180
client.notifyStateChanged(params)
171181
} catch {
@@ -194,48 +204,4 @@ class ClientCoordinator(val server: ViperServerService)(implicit executor: Verif
194204
if (!isAlive) return
195205
client.notifyHint(HintMessage(message, showSettingsButton, showViperToolsUpdateButton ))
196206
}
197-
198-
private def getFileManager(uri: String, content: Option[String] = None): FileManager = {
199-
var createdNew = false
200-
val coordinator = this
201-
val createFMFunc = new java.util.function.Function[String, FileManager]() {
202-
override def apply(t: String): FileManager = {
203-
logger.trace(s"FileManager created for $uri")
204-
createdNew = true
205-
FileManager(uri, coordinator, content)
206-
}
207-
}
208-
// we use `computeIfAbsent` instead of `putIfAbsent` such that a new FileManager is only created if it's absent
209-
val fm = _files.computeIfAbsent(uri, createFMFunc)
210-
// Override the content if we are given one and the file manager was not just created
211-
if (!createdNew && content.isDefined) fm.content.set(content.get)
212-
fm
213-
}
214-
def ensureFmExists(uri: String, content: String): FileManager = {
215-
getFileManager(uri, Some(content))
216-
}
217-
def getRoot(uri: String): FileManager = {
218-
val fm = getFileManager(uri)
219-
fm.projectRoot.map(getFileManager(_)).getOrElse(fm)
220-
}
221-
222-
///////////////////////
223-
// Project management
224-
///////////////////////
225-
226-
def addToProject(uri: String, root: String, getContents: Boolean): (Option[String], Option[Set[String]]) = {
227-
getFileManager(uri).addToProject(root, getContents)
228-
}
229-
def removeFromProject(uri: String, root: String) = {
230-
Option(_files.get(uri)).map(_.removeFromProject(root))
231-
}
232-
def makeEmptyRoot(fm: FileManager) = {
233-
for (leaves <- fm.projectLeaves; leaf <- leaves) {
234-
removeFromProject(leaf, fm.file_uri)
235-
}
236-
fm.project = Left(Map())
237-
}
238-
def handleChangeInLeaf(root: String, leaf: String, range: Range, text: String): Unit = {
239-
Option(_files.get(root)).map(_.handleChangeInLeaf(leaf, range, text))
240-
}
241207
}

src/main/scala/viper/server/frontends/lsp/CommandProtocol.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,8 @@ object C2S_Commands {
2121
// final val GetExecutionTrace = "GetExecutionTrace"
2222
final val RemoveDiagnostics = "RemoveDiagnostics"
2323
final val GetViperFileEndings = "GetViperFileEndings"
24-
final val SetupProject = "SetupProject"
2524
final val FlushCache = "FlushCache"
2625
final val GetIdentifier = "GetIdentifier"
27-
final val GetRange = "GetRange"
2826
}
2927

3028
object S2C_Commands {

0 commit comments

Comments
 (0)