mirror of https://github.com/sbt/sbt.git
begins language server protocol
This is the first cut for the Language Server Protocol on top of server that is still work in progress. With this change, sbt is able to invoke `compile` task on saving files in VS Code.
This commit is contained in:
parent
21bd7c3a91
commit
0c1c380f71
|
|
@ -1,3 +1,8 @@
|
|||
target/
|
||||
__pycache__
|
||||
toolbox.classpath
|
||||
out
|
||||
node_modules
|
||||
vscode-sbt-scala/client/server
|
||||
npm-debug.log
|
||||
*.vsix
|
||||
|
|
|
|||
35
build.sbt
35
build.sbt
|
|
@ -407,6 +407,41 @@ lazy val sbtProj = (project in file("sbt"))
|
|||
)
|
||||
.configure(addSbtCompilerBridge)
|
||||
|
||||
lazy val vscodePlugin = (project in file("vscode-sbt-scala"))
|
||||
.settings(
|
||||
crossPaths := false,
|
||||
crossScalaVersions := Seq(baseScalaVersion),
|
||||
skip in publish := true,
|
||||
compile in Compile := {
|
||||
val u = update.value
|
||||
import sbt.internal.inc.Analysis
|
||||
import scala.sys.process._
|
||||
Process(s"npm run compile", Option(baseDirectory.value)).!
|
||||
Analysis.empty
|
||||
},
|
||||
update := {
|
||||
val old = update.value
|
||||
val t = target.value / "updated"
|
||||
val base = baseDirectory.value
|
||||
if (t.exists) ()
|
||||
else {
|
||||
import scala.sys.process._
|
||||
Process("npm install", Option(base)).!
|
||||
IO.touch(t)
|
||||
}
|
||||
old
|
||||
},
|
||||
cleanFiles ++= {
|
||||
val base = baseDirectory.value
|
||||
Vector(
|
||||
target.value / "updated",
|
||||
base / "node_modules", base / "client" / "node_modules",
|
||||
base / "client" / "server",
|
||||
base / "client" / "out",
|
||||
base / "server" / "node_modules") filter { _.exists }
|
||||
}
|
||||
)
|
||||
|
||||
lazy val sbtIgnoredProblems = {
|
||||
Seq(
|
||||
// Added more items to Import trait.
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ abstract class CommandChannel {
|
|||
commandQueue.add(exec)
|
||||
def poll: Option[Exec] = Option(commandQueue.poll)
|
||||
|
||||
def publishEvent[A: JsonFormat](event: A, execId: Option[String]): Unit
|
||||
def publishEvent[A: JsonFormat](event: A): Unit
|
||||
def publishEventMessage(event: EventMessage): Unit
|
||||
def publishBytes(bytes: Array[Byte]): Unit
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ private[sbt] final class ConsoleChannel(val name: String) extends CommandChannel
|
|||
|
||||
def publishBytes(bytes: Array[Byte]): Unit = ()
|
||||
|
||||
def publishEvent[A: JsonFormat](event: A, execId: Option[String]): Unit = ()
|
||||
|
||||
def publishEvent[A: JsonFormat](event: A): Unit = ()
|
||||
|
||||
def publishEventMessage(event: EventMessage): Unit =
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import sbt.internal.librarymanagement.mavenint.{
|
|||
PomExtraDependencyAttributes,
|
||||
SbtPomExtraProperties
|
||||
}
|
||||
import sbt.internal.server.LanguageServerReporter
|
||||
import sbt.internal.testing.TestLogger
|
||||
import sbt.internal.util._
|
||||
import sbt.internal.util.Attributed.data
|
||||
|
|
@ -1402,6 +1403,14 @@ object Defaults extends BuildCommon {
|
|||
val compilers: Compilers = ci.compilers
|
||||
val i = ci.withCompilers(onArgs(compilers))
|
||||
try {
|
||||
val prev = i.previousResult
|
||||
prev.analysis.toOption map { analysis =>
|
||||
i.setup.reporter match {
|
||||
case r: LanguageServerReporter =>
|
||||
r.resetPrevious(analysis)
|
||||
case _ => ()
|
||||
}
|
||||
}
|
||||
incCompiler.compile(i, s.log)
|
||||
} finally x.close() // workaround for #937
|
||||
}
|
||||
|
|
@ -1441,7 +1450,7 @@ object Defaults extends BuildCommon {
|
|||
compileOrder.value
|
||||
),
|
||||
compilerReporter := {
|
||||
new ManagedLoggedReporter(
|
||||
new LanguageServerReporter(
|
||||
maxErrors.value,
|
||||
streams.value.log,
|
||||
foldMappers(sourcePositionMappers.value)
|
||||
|
|
|
|||
|
|
@ -4,19 +4,21 @@ package internal
|
|||
import java.net.SocketException
|
||||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import sbt.internal.server._
|
||||
import sbt.internal.util.StringEvent
|
||||
import sbt.protocol.{ EventMessage, Serialization }
|
||||
import scala.collection.mutable.ListBuffer
|
||||
import scala.annotation.tailrec
|
||||
import BasicKeys.{ serverHost, serverPort, serverAuthentication }
|
||||
import java.net.Socket
|
||||
import sjsonnew.JsonFormat
|
||||
import sjsonnew.shaded.scalajson.ast.unsafe._
|
||||
import scala.concurrent.Await
|
||||
import scala.concurrent.duration.Duration
|
||||
import scala.util.{ Success, Failure }
|
||||
import sbt.io.syntax._
|
||||
import sbt.io.Hash
|
||||
import sbt.internal.server._
|
||||
import sbt.internal.util.{ StringEvent, ObjectEvent }
|
||||
import sbt.internal.util.codec.JValueFormats
|
||||
import sbt.protocol.{ EventMessage, Serialization, ChannelAcceptedEvent }
|
||||
|
||||
/**
|
||||
* The command exchange merges multiple command channels (e.g. network and console),
|
||||
|
|
@ -34,6 +36,8 @@ private[sbt] final class CommandExchange {
|
|||
private val commandQueue: ConcurrentLinkedQueue[Exec] = new ConcurrentLinkedQueue()
|
||||
private val channelBuffer: ListBuffer[CommandChannel] = new ListBuffer()
|
||||
private val nextChannelId: AtomicInteger = new AtomicInteger(0)
|
||||
private lazy val jsonFormat = new sjsonnew.BasicJsonProtocol with JValueFormats {}
|
||||
|
||||
def channels: List[CommandChannel] = channelBuffer.toList
|
||||
def subscribe(c: CommandChannel): Unit =
|
||||
lock.synchronized {
|
||||
|
|
@ -121,9 +125,31 @@ private[sbt] final class CommandExchange {
|
|||
server = None
|
||||
}
|
||||
|
||||
// This is an interface to directly notify events.
|
||||
private[sbt] def notifyEvent[A: JsonFormat](method: String, params: A): Unit = {
|
||||
val toDel: ListBuffer[CommandChannel] = ListBuffer.empty
|
||||
channels.foreach {
|
||||
case c: ConsoleChannel =>
|
||||
// c.publishEvent(event)
|
||||
case c: NetworkChannel =>
|
||||
try {
|
||||
c.notifyEvent(method, params)
|
||||
} catch {
|
||||
case e: SocketException =>
|
||||
toDel += c
|
||||
}
|
||||
}
|
||||
toDel.toList match {
|
||||
case Nil => // do nothing
|
||||
case xs =>
|
||||
lock.synchronized {
|
||||
channelBuffer --= xs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def publishEvent[A: JsonFormat](event: A): Unit = {
|
||||
val toDel: ListBuffer[CommandChannel] = ListBuffer.empty
|
||||
val bytes = Serialization.serializeEvent(event)
|
||||
event match {
|
||||
case entry: StringEvent =>
|
||||
channels.foreach {
|
||||
|
|
@ -134,7 +160,7 @@ private[sbt] final class CommandExchange {
|
|||
case c: NetworkChannel =>
|
||||
try {
|
||||
if (entry.channelName == Some(c.name)) {
|
||||
c.publishBytes(bytes)
|
||||
c.publishEvent(event)
|
||||
}
|
||||
} catch {
|
||||
case e: SocketException =>
|
||||
|
|
@ -147,7 +173,7 @@ private[sbt] final class CommandExchange {
|
|||
c.publishEvent(event)
|
||||
case c: NetworkChannel =>
|
||||
try {
|
||||
c.publishBytes(bytes)
|
||||
c.publishEvent(event)
|
||||
} catch {
|
||||
case e: SocketException =>
|
||||
toDel += c
|
||||
|
|
@ -163,6 +189,43 @@ private[sbt] final class CommandExchange {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This publishes object events. The type information has been
|
||||
* erased because it went through logging.
|
||||
*/
|
||||
private[sbt] def publishObjectEvent(event: ObjectEvent[_]): Unit = {
|
||||
import jsonFormat._
|
||||
val toDel: ListBuffer[CommandChannel] = ListBuffer.empty
|
||||
def json: JValue = JObject(
|
||||
JField("type", JString(event.contentType)),
|
||||
(Vector(JField("message", event.json), JField("level", JString(event.level.toString))) ++
|
||||
(event.channelName.toVector map { channelName =>
|
||||
JField("channelName", JString(channelName))
|
||||
}) ++
|
||||
(event.execId.toVector map { execId =>
|
||||
JField("execId", JString(execId))
|
||||
})): _*
|
||||
)
|
||||
channels.foreach {
|
||||
case c: ConsoleChannel =>
|
||||
c.publishEvent(json)
|
||||
case c: NetworkChannel =>
|
||||
try {
|
||||
c.publishObjectEvent(event)
|
||||
} catch {
|
||||
case e: SocketException =>
|
||||
toDel += c
|
||||
}
|
||||
}
|
||||
toDel.toList match {
|
||||
case Nil => // do nothing
|
||||
case xs =>
|
||||
lock.synchronized {
|
||||
channelBuffer --= xs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fanout publishEvent
|
||||
def publishEventMessage(event: EventMessage): Unit = {
|
||||
val toDel: ListBuffer[CommandChannel] = ListBuffer.empty
|
||||
|
|
@ -177,14 +240,12 @@ private[sbt] final class CommandExchange {
|
|||
case c: ConsoleChannel => c.publishEventMessage(e)
|
||||
}
|
||||
case _ =>
|
||||
// TODO do not do this on the calling thread
|
||||
val bytes = Serialization.serializeEventMessage(event)
|
||||
channels.foreach {
|
||||
case c: ConsoleChannel =>
|
||||
c.publishEventMessage(event)
|
||||
case c: NetworkChannel =>
|
||||
try {
|
||||
c.publishBytes(bytes)
|
||||
c.publishEventMessage(event)
|
||||
} catch {
|
||||
case e: SocketException =>
|
||||
toDel += c
|
||||
|
|
|
|||
|
|
@ -10,12 +10,10 @@ import sbt.util.Level
|
|||
import sbt.internal.util._
|
||||
import sbt.protocol.LogEvent
|
||||
import sbt.internal.util.codec._
|
||||
import sjsonnew.shaded.scalajson.ast.unsafe._
|
||||
|
||||
class RelayAppender(name: String)
|
||||
extends AbstractAppender(name, null, PatternLayout.createDefaultLayout(), true) {
|
||||
lazy val exchange = StandardMain.exchange
|
||||
lazy val jsonFormat = new sjsonnew.BasicJsonProtocol with JValueFormats {}
|
||||
|
||||
def append(event: XLogEvent): Unit = {
|
||||
val level = ConsoleAppender.toLevel(event.getLevel)
|
||||
|
|
@ -36,20 +34,7 @@ class RelayAppender(name: String)
|
|||
import JsonProtocol._
|
||||
exchange.publishEvent(x: AbstractEntry)
|
||||
}
|
||||
case x: ObjectEvent[_] => {
|
||||
import jsonFormat._
|
||||
val json = JObject(
|
||||
JField("type", JString(x.contentType)),
|
||||
(Vector(JField("message", x.json), JField("level", JString(x.level.toString))) ++
|
||||
(x.channelName.toVector map { channelName =>
|
||||
JField("channelName", JString(channelName))
|
||||
}) ++
|
||||
(x.execId.toVector map { execId =>
|
||||
JField("execId", JString(execId))
|
||||
})): _*
|
||||
)
|
||||
exchange.publishEvent(json: JValue)
|
||||
}
|
||||
case x: ObjectEvent[_] => exchange.publishObjectEvent(x)
|
||||
case _ =>
|
||||
println(s"appendEvent: ${event.getClass}")
|
||||
()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,127 @@
|
|||
package sbt
|
||||
package internal
|
||||
package server
|
||||
|
||||
import sjsonnew.JsonFormat
|
||||
import sjsonnew.support.scalajson.unsafe.Converter
|
||||
import sbt.protocol.Serialization
|
||||
import sbt.internal.protocol._
|
||||
import sbt.internal.protocol.codec._
|
||||
import sbt.internal.langserver._
|
||||
import sbt.internal.util.ObjectEvent
|
||||
|
||||
private[sbt] case class LangServerError(code: Long, message: String) extends Throwable(message)
|
||||
|
||||
/**
|
||||
* Implements Language Server Protocol <https://github.com/Microsoft/language-server-protocol>.
|
||||
*/
|
||||
private[sbt] trait LanguageServerProtocol extends CommandChannel {
|
||||
|
||||
lazy val internalJsonProtocol = new InitializeOptionFormats with sjsonnew.BasicJsonProtocol {}
|
||||
|
||||
protected def authenticate(token: String): Boolean
|
||||
protected def authOptions: Set[ServerAuthentication]
|
||||
protected def setInitialized(value: Boolean): Unit
|
||||
|
||||
protected def onRequestMessage(request: JsonRpcRequestMessage): Unit = {
|
||||
|
||||
import sbt.internal.langserver.codec.JsonProtocol._
|
||||
import internalJsonProtocol._
|
||||
|
||||
println(s"onRequestMessage: $request")
|
||||
request.method match {
|
||||
case "initialize" =>
|
||||
if (authOptions(ServerAuthentication.Token)) {
|
||||
val json =
|
||||
request.params.getOrElse(
|
||||
throw LangServerError(ErrorCodes.InvalidParams,
|
||||
"param is expected on 'initialize' method."))
|
||||
val param = Converter.fromJson[InitializeParams](json).get
|
||||
val optionJson = param.initializationOptions.getOrElse(
|
||||
throw LangServerError(ErrorCodes.InvalidParams,
|
||||
"initializationOptions is expected on 'initialize' param."))
|
||||
val opt = Converter.fromJson[InitializeOption](optionJson).get
|
||||
val token = opt.token.getOrElse(sys.error("'token' is missing."))
|
||||
if (authenticate(token)) ()
|
||||
else throw LangServerError(ErrorCodes.InvalidRequest, "invalid token")
|
||||
} else ()
|
||||
setInitialized(true)
|
||||
langRespond(InitializeResult(serverCapabilities), Option(request.id))
|
||||
case "textDocument/didSave" =>
|
||||
append(Exec("compile", Some(request.id), Some(CommandSource(name))))
|
||||
case _ => ()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This reacts to various events that happens inside sbt, sometime
|
||||
* in response to the previous requests.
|
||||
* The type information has been erased because it went through logging.
|
||||
*/
|
||||
protected def onObjectEvent(event: ObjectEvent[_]): Unit = {
|
||||
// import sbt.internal.langserver.codec.JsonProtocol._
|
||||
|
||||
val msgContentType = event.contentType
|
||||
msgContentType match {
|
||||
// LanguageServerReporter sends PublishDiagnosticsParams
|
||||
case "sbt.internal.langserver.PublishDiagnosticsParams" =>
|
||||
// val p = event.message.asInstanceOf[PublishDiagnosticsParams]
|
||||
// langNotify("textDocument/publishDiagnostics", p)
|
||||
case "xsbti.Problem" =>
|
||||
() // ignore
|
||||
case _ =>
|
||||
// println(event)
|
||||
()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond back to Language Server's client.
|
||||
*/
|
||||
private[sbt] def langRespond[A: JsonFormat](event: A, execId: Option[String]): Unit = {
|
||||
val m =
|
||||
JsonRpcResponseMessage("2.0", execId, Option(Converter.toJson[A](event).get), None)
|
||||
val bytes = Serialization.serializeResponseMessage(m)
|
||||
publishBytes(bytes)
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond back to Language Server's client.
|
||||
*/
|
||||
private[sbt] def langError(execId: Option[String], code: Long, message: String): Unit = {
|
||||
val e = JsonRpcResponseError(code, message, None)
|
||||
val m = JsonRpcResponseMessage("2.0", execId, None, Option(e))
|
||||
val bytes = Serialization.serializeResponseMessage(m)
|
||||
publishBytes(bytes)
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond back to Language Server's client.
|
||||
*/
|
||||
private[sbt] def langError[A: JsonFormat](execId: Option[String],
|
||||
code: Long,
|
||||
message: String,
|
||||
data: A): Unit = {
|
||||
val e = JsonRpcResponseError(code, message, Option(Converter.toJson[A](data).get))
|
||||
val m = JsonRpcResponseMessage("2.0", execId, None, Option(e))
|
||||
val bytes = Serialization.serializeResponseMessage(m)
|
||||
publishBytes(bytes)
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify to Language Server's client.
|
||||
*/
|
||||
private[sbt] def langNotify[A: JsonFormat](method: String, params: A): Unit = {
|
||||
val m =
|
||||
JsonRpcNotificationMessage("2.0", method, Option(Converter.toJson[A](params).get))
|
||||
println(s"langNotify: $m")
|
||||
val bytes = Serialization.serializeNotificationMessage(m)
|
||||
publishBytes(bytes)
|
||||
}
|
||||
|
||||
private[sbt] lazy val serverCapabilities: ServerCapabilities = {
|
||||
ServerCapabilities(textDocumentSync =
|
||||
TextDocumentSyncOptions(true, 0, false, false, SaveOptions(false)),
|
||||
hoverProvider = false)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
package sbt
|
||||
package internal
|
||||
package server
|
||||
|
||||
import java.io.File
|
||||
import sbt.internal.inc.ManagedLoggedReporter
|
||||
import sbt.internal.util.ManagedLogger
|
||||
import xsbti.{ Problem, Position => XPosition, Severity }
|
||||
import xsbti.compile.CompileAnalysis
|
||||
import sbt.internal.langserver.{
|
||||
PublishDiagnosticsParams,
|
||||
Position,
|
||||
Diagnostic,
|
||||
Range,
|
||||
DiagnosticSeverity
|
||||
}
|
||||
import sbt.internal.inc.JavaInterfaceUtil._
|
||||
import scala.collection.mutable
|
||||
import scala.collection.JavaConverters._
|
||||
|
||||
/**
|
||||
* Defines a compiler reporter that uses event logging provided by a [[ManagedLogger]].
|
||||
*
|
||||
* @param maximumErrors The maximum errors.
|
||||
* @param logger The event managed logger.
|
||||
* @param sourcePositionMapper The position mapper.
|
||||
*/
|
||||
class LanguageServerReporter(
|
||||
maximumErrors: Int,
|
||||
logger: ManagedLogger,
|
||||
sourcePositionMapper: XPosition => XPosition = identity[XPosition]
|
||||
) extends ManagedLoggedReporter(maximumErrors, logger, sourcePositionMapper) {
|
||||
lazy val exchange = StandardMain.exchange
|
||||
|
||||
private[sbt] lazy val problemsByFile = new mutable.HashMap[File, List[Problem]]
|
||||
|
||||
override def reset(): Unit = {
|
||||
super.reset()
|
||||
problemsByFile.clear()
|
||||
}
|
||||
|
||||
override def log(problem: Problem): Unit = {
|
||||
val pos = problem.position
|
||||
pos.sourceFile.toOption foreach { sourceFile: File =>
|
||||
problemsByFile.get(sourceFile) match {
|
||||
case Some(xs: List[Problem]) => problemsByFile(sourceFile) = problem :: xs
|
||||
case _ => problemsByFile(sourceFile) = List(problem)
|
||||
}
|
||||
}
|
||||
super.log(problem)
|
||||
}
|
||||
|
||||
override def logError(problem: Problem): Unit = {
|
||||
aggregateProblems(problem)
|
||||
|
||||
// console channel can keep using the xsbi.Problem
|
||||
super.logError(problem)
|
||||
}
|
||||
|
||||
override def logWarning(problem: Problem): Unit = {
|
||||
aggregateProblems(problem)
|
||||
|
||||
// console channel can keep using the xsbi.Problem
|
||||
super.logWarning(problem)
|
||||
}
|
||||
|
||||
override def logInfo(problem: Problem): Unit = {
|
||||
aggregateProblems(problem)
|
||||
|
||||
// console channel can keep using the xsbi.Problem
|
||||
super.logInfo(problem)
|
||||
}
|
||||
|
||||
private[sbt] def resetPrevious(analysis: CompileAnalysis): Unit = {
|
||||
import sbt.internal.langserver.codec.JsonProtocol._
|
||||
val files = analysis.readSourceInfos.getAllSourceInfos.keySet.asScala
|
||||
println(files)
|
||||
files foreach { f =>
|
||||
val params = PublishDiagnosticsParams(f.toURI.toString, Vector())
|
||||
exchange.notifyEvent("textDocument/publishDiagnostics", params)
|
||||
}
|
||||
}
|
||||
|
||||
private[sbt] def aggregateProblems(problem: Problem): Unit = {
|
||||
import sbt.internal.langserver.codec.JsonProtocol._
|
||||
val pos = problem.position
|
||||
pos.sourceFile.toOption foreach { sourceFile: File =>
|
||||
problemsByFile.get(sourceFile) match {
|
||||
case Some(xs: List[Problem]) =>
|
||||
val ds = toDiagnostics(xs)
|
||||
val params = PublishDiagnosticsParams(sourceFile.toURI.toString, ds)
|
||||
exchange.notifyEvent("textDocument/publishDiagnostics", params)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private[sbt] def toDiagnostics(ps: List[Problem]): Vector[Diagnostic] = {
|
||||
for {
|
||||
problem <- ps.toVector
|
||||
pos = problem.position
|
||||
line0 <- pos.line.toOption.toVector
|
||||
pointer0 <- pos.pointer.toOption.toVector
|
||||
} yield {
|
||||
val line = line0.toLong - 1L
|
||||
val pointer = pointer0.toLong
|
||||
Diagnostic(
|
||||
Range(start = Position(line, pointer), end = Position(line, pointer + 1)),
|
||||
Option(toDiagnosticSeverity(problem.severity)),
|
||||
None,
|
||||
Option("sbt"),
|
||||
problem.message
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private[sbt] def toDiagnosticSeverity(severity: Severity): Long = severity match {
|
||||
case Severity.Info => DiagnosticSeverity.Information
|
||||
case Severity.Warn => DiagnosticSeverity.Warning
|
||||
case Severity.Error => DiagnosticSeverity.Error
|
||||
}
|
||||
}
|
||||
|
|
@ -7,21 +7,58 @@ package server
|
|||
|
||||
import java.net.{ Socket, SocketTimeoutException }
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import sbt.protocol._
|
||||
|
||||
import sjsonnew._
|
||||
import sjsonnew.support.scalajson.unsafe.Converter
|
||||
import scala.annotation.tailrec
|
||||
import sbt.protocol._
|
||||
import sbt.internal.langserver.ErrorCodes
|
||||
import sbt.internal.protocol.JsonRpcResponseMessage
|
||||
import sbt.internal.util.ObjectEvent
|
||||
import sbt.internal.util.codec.JValueFormats
|
||||
|
||||
final class NetworkChannel(val name: String,
|
||||
connection: Socket,
|
||||
structure: BuildStructure,
|
||||
auth: Set[ServerAuthentication],
|
||||
instance: ServerInstance)
|
||||
extends CommandChannel {
|
||||
extends CommandChannel
|
||||
with LanguageServerProtocol {
|
||||
import NetworkChannel._
|
||||
|
||||
private val running = new AtomicBoolean(true)
|
||||
private val delimiter: Byte = '\n'.toByte
|
||||
private val RetByte = '\r'.toByte
|
||||
private val out = connection.getOutputStream
|
||||
private var initialized = false
|
||||
private val Curly = '{'.toByte
|
||||
private val ContentLength = """^Content\-Length\:\s*(\d+)""".r
|
||||
private val ContentType = """^Content\-Type\:\s*(.+)""".r
|
||||
private var _contentType: String = ""
|
||||
private val SbtX1Protocol = "application/sbt-x1"
|
||||
private val VsCode = sbt.protocol.Serialization.VsCode
|
||||
private val VsCodeOld = "application/vscode-jsonrpc; charset=utf8"
|
||||
private lazy val jsonFormat = new sjsonnew.BasicJsonProtocol with JValueFormats {}
|
||||
|
||||
def setContentType(ct: String): Unit = synchronized {
|
||||
_contentType = ct
|
||||
}
|
||||
def contentType: String = _contentType
|
||||
|
||||
protected def authenticate(token: String): Boolean = {
|
||||
instance.authenticate(token)
|
||||
}
|
||||
|
||||
protected def setInitialized(value: Boolean): Unit = {
|
||||
initialized = value
|
||||
}
|
||||
|
||||
protected def authOptions: Set[ServerAuthentication] = auth
|
||||
|
||||
val thread = new Thread(s"sbt-networkchannel-${connection.getPort}") {
|
||||
var contentLength: Int = 0
|
||||
var state: ChannelState = SingleLine
|
||||
|
||||
override def run(): Unit = {
|
||||
try {
|
||||
val readBuffer = new Array[Byte](4096)
|
||||
|
|
@ -29,48 +66,221 @@ final class NetworkChannel(val name: String,
|
|||
connection.setSoTimeout(5000)
|
||||
var buffer: Vector[Byte] = Vector.empty
|
||||
var bytesRead = 0
|
||||
def resetChannelState(): Unit = {
|
||||
contentLength = 0
|
||||
// contentType = ""
|
||||
state = SingleLine
|
||||
}
|
||||
|
||||
def tillEndOfLine: Option[Vector[Byte]] = {
|
||||
val delimPos = buffer.indexOf(delimiter)
|
||||
if (delimPos > 0) {
|
||||
val chunk0 = buffer.take(delimPos)
|
||||
buffer = buffer.drop(delimPos + 1)
|
||||
// remove \r at the end of line.
|
||||
if (chunk0.size > 0 && chunk0.indexOf(RetByte) == chunk0.size - 1)
|
||||
Some(chunk0.dropRight(1))
|
||||
else Some(chunk0)
|
||||
} else None // no EOL yet, so skip this turn.
|
||||
}
|
||||
|
||||
def tillContentLength: Option[Vector[Byte]] = {
|
||||
if (contentLength <= buffer.size) {
|
||||
val chunk = buffer.take(contentLength)
|
||||
buffer = buffer.drop(contentLength)
|
||||
resetChannelState()
|
||||
Some(chunk)
|
||||
} else None // have not read enough yet, so skip this turn.
|
||||
}
|
||||
|
||||
@tailrec def process(): Unit = {
|
||||
// handle un-framing
|
||||
state match {
|
||||
case SingleLine =>
|
||||
tillEndOfLine match {
|
||||
case Some(chunk) =>
|
||||
chunk.headOption match {
|
||||
case None => // ignore blank line
|
||||
case Some(Curly) =>
|
||||
Serialization
|
||||
.deserializeCommand(chunk)
|
||||
.fold(
|
||||
errorDesc =>
|
||||
println(
|
||||
s"Got invalid chunk from client (${new String(chunk.toArray, "UTF-8")}): " + errorDesc),
|
||||
onCommand
|
||||
)
|
||||
resetChannelState()
|
||||
case Some(_) =>
|
||||
val str = (new String(chunk.toArray, "UTF-8")).trim
|
||||
handleHeader(str) match {
|
||||
case Some(_) =>
|
||||
state = InHeader
|
||||
process()
|
||||
case _ => println("Got invalid chunk from client: " + str)
|
||||
}
|
||||
}
|
||||
case _ => ()
|
||||
}
|
||||
case InHeader =>
|
||||
tillEndOfLine match {
|
||||
case Some(chunk) =>
|
||||
val str = (new String(chunk.toArray, "UTF-8")).trim
|
||||
if (str == "") {
|
||||
state = InBody
|
||||
process()
|
||||
} else
|
||||
handleHeader(str) match {
|
||||
case Some(_) => process()
|
||||
case _ =>
|
||||
println("Got invalid header from client: " + str)
|
||||
resetChannelState()
|
||||
}
|
||||
case _ => ()
|
||||
}
|
||||
case InBody =>
|
||||
tillContentLength match {
|
||||
case Some(chunk) =>
|
||||
handleBody(chunk)
|
||||
process()
|
||||
case _ => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// keep going unless the socket has closed
|
||||
while (bytesRead != -1 && running.get) {
|
||||
try {
|
||||
bytesRead = in.read(readBuffer)
|
||||
buffer = buffer ++ readBuffer.toVector.take(bytesRead)
|
||||
// handle un-framing
|
||||
var delimPos = buffer.indexOf(delimiter)
|
||||
while (delimPos > -1) {
|
||||
val chunk = buffer.take(delimPos)
|
||||
buffer = buffer.drop(delimPos + 1)
|
||||
|
||||
Serialization
|
||||
.deserializeCommand(chunk)
|
||||
.fold(
|
||||
errorDesc => println("Got invalid chunk from client: " + errorDesc),
|
||||
onCommand
|
||||
)
|
||||
delimPos = buffer.indexOf(delimiter)
|
||||
println(s"bytesRead: $bytesRead")
|
||||
if (bytesRead > 0) {
|
||||
buffer = buffer ++ readBuffer.toVector.take(bytesRead)
|
||||
}
|
||||
process()
|
||||
} catch {
|
||||
case _: SocketTimeoutException => // its ok
|
||||
}
|
||||
}
|
||||
} // while
|
||||
} finally {
|
||||
shutdown()
|
||||
}
|
||||
}
|
||||
|
||||
def handleBody(chunk: Vector[Byte]): Unit = {
|
||||
if (isLanguageServerProtocol) {
|
||||
Serialization.deserializeJsonRequest(chunk) match {
|
||||
case Right(req) =>
|
||||
try {
|
||||
onRequestMessage(req)
|
||||
} catch {
|
||||
case LangServerError(code, message) =>
|
||||
println(s"sending error: $code: $message")
|
||||
langError(Option(req.id), code, message)
|
||||
}
|
||||
case Left(errorDesc) =>
|
||||
val msg = s"Got invalid chunk from client (${new String(chunk.toArray, "UTF-8")}): " + errorDesc
|
||||
langError(None, ErrorCodes.ParseError, msg)
|
||||
}
|
||||
} else {
|
||||
contentType match {
|
||||
case SbtX1Protocol =>
|
||||
Serialization
|
||||
.deserializeCommand(chunk)
|
||||
.fold(
|
||||
errorDesc =>
|
||||
println(
|
||||
s"Got invalid chunk from client (${new String(chunk.toArray, "UTF-8")}): " + errorDesc),
|
||||
onCommand
|
||||
)
|
||||
case _ =>
|
||||
println(s"Unknown Content-Type: $contentType")
|
||||
}
|
||||
} // if-else
|
||||
}
|
||||
|
||||
def handleHeader(str: String): Option[Unit] = {
|
||||
str match {
|
||||
case ContentLength(len) =>
|
||||
contentLength = len.toInt
|
||||
Some(())
|
||||
case ContentType(ct) =>
|
||||
setContentType(ct)
|
||||
Some(())
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
thread.start()
|
||||
|
||||
def publishEvent[A: JsonFormat](event: A): Unit = {
|
||||
val bytes = Serialization.serializeEvent(event)
|
||||
publishBytes(bytes)
|
||||
private[sbt] def isLanguageServerProtocol: Boolean = {
|
||||
contentType match {
|
||||
case "" | VsCode | VsCodeOld => true
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
|
||||
private[sbt] def notifyEvent[A: JsonFormat](method: String, params: A): Unit = {
|
||||
if (isLanguageServerProtocol) {
|
||||
langNotify(method, params)
|
||||
} else {
|
||||
()
|
||||
}
|
||||
}
|
||||
|
||||
def publishEvent[A: JsonFormat](event: A, execId: Option[String]): Unit = {
|
||||
if (isLanguageServerProtocol) {
|
||||
langRespond(event, execId)
|
||||
} else {
|
||||
contentType match {
|
||||
case SbtX1Protocol =>
|
||||
val bytes = Serialization.serializeEvent(event)
|
||||
publishBytes(bytes, true)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def publishEvent[A: JsonFormat](event: A): Unit = publishEvent(event, None)
|
||||
|
||||
def publishEventMessage(event: EventMessage): Unit = {
|
||||
val bytes = Serialization.serializeEventMessage(event)
|
||||
publishBytes(bytes)
|
||||
contentType match {
|
||||
case SbtX1Protocol =>
|
||||
val bytes = Serialization.serializeEventMessage(event)
|
||||
publishBytes(bytes, true)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
def publishBytes(event: Array[Byte]): Unit = {
|
||||
/**
|
||||
* This publishes object events. The type information has been
|
||||
* erased because it went through logging.
|
||||
*/
|
||||
private[sbt] def publishObjectEvent(event: ObjectEvent[_]): Unit = {
|
||||
import sjsonnew.shaded.scalajson.ast.unsafe._
|
||||
if (isLanguageServerProtocol) onObjectEvent(event)
|
||||
else {
|
||||
import jsonFormat._
|
||||
val json: JValue = JObject(
|
||||
JField("type", JString(event.contentType)),
|
||||
(Vector(JField("message", event.json), JField("level", JString(event.level.toString))) ++
|
||||
(event.channelName.toVector map { channelName =>
|
||||
JField("channelName", JString(channelName))
|
||||
}) ++
|
||||
(event.execId.toVector map { execId =>
|
||||
JField("execId", JString(execId))
|
||||
})): _*
|
||||
)
|
||||
publishEvent(json)
|
||||
}
|
||||
}
|
||||
|
||||
def publishBytes(event: Array[Byte]): Unit = publishBytes(event, false)
|
||||
|
||||
def publishBytes(event: Array[Byte], delimit: Boolean): Unit = {
|
||||
out.write(event)
|
||||
out.write(delimiter.toInt)
|
||||
if (delimit) {
|
||||
out.write(delimiter.toInt)
|
||||
}
|
||||
out.flush()
|
||||
}
|
||||
|
||||
|
|
@ -84,7 +294,7 @@ final class NetworkChannel(val name: String,
|
|||
if (auth(ServerAuthentication.Token)) {
|
||||
cmd.token match {
|
||||
case Some(x) =>
|
||||
instance.authenticate(x) match {
|
||||
authenticate(x) match {
|
||||
case true =>
|
||||
initialized = true
|
||||
publishEventMessage(ChannelAcceptedEvent(name))
|
||||
|
|
@ -120,3 +330,10 @@ final class NetworkChannel(val name: String,
|
|||
out.close()
|
||||
}
|
||||
}
|
||||
|
||||
object NetworkChannel {
|
||||
sealed trait ChannelState
|
||||
case object SingleLine extends ChannelState
|
||||
case object InHeader extends ChannelState
|
||||
case object InBody extends ChannelState
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ object Dependencies {
|
|||
|
||||
// sbt modules
|
||||
private val ioVersion = "1.1.0"
|
||||
private val utilVersion = "1.0.1"
|
||||
private val utilVersion = "1.0.2"
|
||||
private val lmVersion = "1.0.2"
|
||||
private val zincVersion = "1.0.1"
|
||||
private val zincVersion = "1.0.2"
|
||||
|
||||
private val sbtIO = "org.scala-sbt" %% "io" % ioVersion
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@ addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.17")
|
|||
// addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "1.2.0")
|
||||
|
||||
addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.5.1")
|
||||
addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0")
|
||||
addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.1")
|
||||
addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.0-M1")
|
||||
addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.10")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||
trait InitializeResultFormats { self: ServerCapabilitiesFormats with sjsonnew.BasicJsonProtocol =>
|
||||
implicit lazy val InitializeResultFormat: JsonFormat[sbt.internal.langserver.InitializeResult] = new JsonFormat[sbt.internal.langserver.InitializeResult] {
|
||||
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.InitializeResult = {
|
||||
jsOpt match {
|
||||
case Some(js) =>
|
||||
unbuilder.beginObject(js)
|
||||
val capabilities = unbuilder.readField[Option[sbt.internal.langserver.ServerCapabilities]]("capabilities")
|
||||
unbuilder.endObject()
|
||||
sbt.internal.langserver.InitializeResult(capabilities)
|
||||
case None =>
|
||||
deserializationError("Expected JsObject but found None")
|
||||
}
|
||||
}
|
||||
override def write[J](obj: sbt.internal.langserver.InitializeResult, builder: Builder[J]): Unit = {
|
||||
builder.beginObject()
|
||||
builder.addField("capabilities", obj.capabilities)
|
||||
builder.endObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||
trait ServerCapabilitiesFormats { self: sjsonnew.BasicJsonProtocol =>
|
||||
implicit lazy val ServerCapabilitiesFormat: JsonFormat[sbt.internal.langserver.ServerCapabilities] = new JsonFormat[sbt.internal.langserver.ServerCapabilities] {
|
||||
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.ServerCapabilities = {
|
||||
jsOpt match {
|
||||
case Some(js) =>
|
||||
unbuilder.beginObject(js)
|
||||
val hoverProvider = unbuilder.readField[Option[Boolean]]("hoverProvider")
|
||||
unbuilder.endObject()
|
||||
sbt.internal.langserver.ServerCapabilities(hoverProvider)
|
||||
case None =>
|
||||
deserializationError("Expected JsObject but found None")
|
||||
}
|
||||
}
|
||||
override def write[J](obj: sbt.internal.langserver.ServerCapabilities, builder: Builder[J]): Unit = {
|
||||
builder.beginObject()
|
||||
builder.addField("hoverProvider", obj.hoverProvider)
|
||||
builder.endObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver
|
||||
final class ClientCapabilities private () extends Serializable {
|
||||
|
||||
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case x: ClientCapabilities => true
|
||||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = {
|
||||
37 * (17 + "sbt.internal.langserver.ClientCapabilities".##)
|
||||
}
|
||||
override def toString: String = {
|
||||
"ClientCapabilities()"
|
||||
}
|
||||
protected[this] def copy(): ClientCapabilities = {
|
||||
new ClientCapabilities()
|
||||
}
|
||||
|
||||
}
|
||||
object ClientCapabilities {
|
||||
|
||||
def apply(): ClientCapabilities = new ClientCapabilities()
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver
|
||||
/**
|
||||
* Represents a diagnostic, such as a compiler error or warning.
|
||||
* Diagnostic objects are only valid in the scope of a resource.
|
||||
*/
|
||||
final class Diagnostic private (
|
||||
/** The range at which the message applies. */
|
||||
val range: sbt.internal.langserver.Range,
|
||||
/**
|
||||
* The diagnostic's severity. Can be omitted. If omitted it is up to the
|
||||
* client to interpret diagnostics as error, warning, info or hint.
|
||||
*/
|
||||
val severity: Option[Long],
|
||||
/** The diagnostic's code. Can be omitted. */
|
||||
val code: Option[String],
|
||||
/**
|
||||
* A human-readable string describing the source of this
|
||||
* diagnostic, e.g. 'typescript' or 'super lint'.
|
||||
*/
|
||||
val source: Option[String],
|
||||
/** The diagnostic's message. */
|
||||
val message: String) extends Serializable {
|
||||
|
||||
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case x: Diagnostic => (this.range == x.range) && (this.severity == x.severity) && (this.code == x.code) && (this.source == x.source) && (this.message == x.message)
|
||||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = {
|
||||
37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.langserver.Diagnostic".##) + range.##) + severity.##) + code.##) + source.##) + message.##)
|
||||
}
|
||||
override def toString: String = {
|
||||
"Diagnostic(" + range + ", " + severity + ", " + code + ", " + source + ", " + message + ")"
|
||||
}
|
||||
protected[this] def copy(range: sbt.internal.langserver.Range = range, severity: Option[Long] = severity, code: Option[String] = code, source: Option[String] = source, message: String = message): Diagnostic = {
|
||||
new Diagnostic(range, severity, code, source, message)
|
||||
}
|
||||
def withRange(range: sbt.internal.langserver.Range): Diagnostic = {
|
||||
copy(range = range)
|
||||
}
|
||||
def withSeverity(severity: Option[Long]): Diagnostic = {
|
||||
copy(severity = severity)
|
||||
}
|
||||
def withSeverity(severity: Long): Diagnostic = {
|
||||
copy(severity = Option(severity))
|
||||
}
|
||||
def withCode(code: Option[String]): Diagnostic = {
|
||||
copy(code = code)
|
||||
}
|
||||
def withCode(code: String): Diagnostic = {
|
||||
copy(code = Option(code))
|
||||
}
|
||||
def withSource(source: Option[String]): Diagnostic = {
|
||||
copy(source = source)
|
||||
}
|
||||
def withSource(source: String): Diagnostic = {
|
||||
copy(source = Option(source))
|
||||
}
|
||||
def withMessage(message: String): Diagnostic = {
|
||||
copy(message = message)
|
||||
}
|
||||
}
|
||||
object Diagnostic {
|
||||
|
||||
def apply(range: sbt.internal.langserver.Range, severity: Option[Long], code: Option[String], source: Option[String], message: String): Diagnostic = new Diagnostic(range, severity, code, source, message)
|
||||
def apply(range: sbt.internal.langserver.Range, severity: Long, code: String, source: String, message: String): Diagnostic = new Diagnostic(range, Option(severity), Option(code), Option(source), message)
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver
|
||||
final class InitializeParams private (
|
||||
val processId: Option[Long],
|
||||
/** The rootPath of the workspace. */
|
||||
val rootPath: Option[String],
|
||||
val rootUri: Option[String],
|
||||
val initializationOptions: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue],
|
||||
val capabilities: Option[sbt.internal.langserver.ClientCapabilities],
|
||||
val trace: Option[String]) extends Serializable {
|
||||
|
||||
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case x: InitializeParams => (this.processId == x.processId) && (this.rootPath == x.rootPath) && (this.rootUri == x.rootUri) && (this.initializationOptions == x.initializationOptions) && (this.capabilities == x.capabilities) && (this.trace == x.trace)
|
||||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = {
|
||||
37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.langserver.InitializeParams".##) + processId.##) + rootPath.##) + rootUri.##) + initializationOptions.##) + capabilities.##) + trace.##)
|
||||
}
|
||||
override def toString: String = {
|
||||
"InitializeParams(" + processId + ", " + rootPath + ", " + rootUri + ", " + initializationOptions + ", " + capabilities + ", " + trace + ")"
|
||||
}
|
||||
protected[this] def copy(processId: Option[Long] = processId, rootPath: Option[String] = rootPath, rootUri: Option[String] = rootUri, initializationOptions: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue] = initializationOptions, capabilities: Option[sbt.internal.langserver.ClientCapabilities] = capabilities, trace: Option[String] = trace): InitializeParams = {
|
||||
new InitializeParams(processId, rootPath, rootUri, initializationOptions, capabilities, trace)
|
||||
}
|
||||
def withProcessId(processId: Option[Long]): InitializeParams = {
|
||||
copy(processId = processId)
|
||||
}
|
||||
def withProcessId(processId: Long): InitializeParams = {
|
||||
copy(processId = Option(processId))
|
||||
}
|
||||
def withRootPath(rootPath: Option[String]): InitializeParams = {
|
||||
copy(rootPath = rootPath)
|
||||
}
|
||||
def withRootPath(rootPath: String): InitializeParams = {
|
||||
copy(rootPath = Option(rootPath))
|
||||
}
|
||||
def withRootUri(rootUri: Option[String]): InitializeParams = {
|
||||
copy(rootUri = rootUri)
|
||||
}
|
||||
def withRootUri(rootUri: String): InitializeParams = {
|
||||
copy(rootUri = Option(rootUri))
|
||||
}
|
||||
def withInitializationOptions(initializationOptions: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]): InitializeParams = {
|
||||
copy(initializationOptions = initializationOptions)
|
||||
}
|
||||
def withInitializationOptions(initializationOptions: sjsonnew.shaded.scalajson.ast.unsafe.JValue): InitializeParams = {
|
||||
copy(initializationOptions = Option(initializationOptions))
|
||||
}
|
||||
def withCapabilities(capabilities: Option[sbt.internal.langserver.ClientCapabilities]): InitializeParams = {
|
||||
copy(capabilities = capabilities)
|
||||
}
|
||||
def withCapabilities(capabilities: sbt.internal.langserver.ClientCapabilities): InitializeParams = {
|
||||
copy(capabilities = Option(capabilities))
|
||||
}
|
||||
def withTrace(trace: Option[String]): InitializeParams = {
|
||||
copy(trace = trace)
|
||||
}
|
||||
def withTrace(trace: String): InitializeParams = {
|
||||
copy(trace = Option(trace))
|
||||
}
|
||||
}
|
||||
object InitializeParams {
|
||||
|
||||
def apply(processId: Option[Long], rootPath: Option[String], rootUri: Option[String], initializationOptions: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue], capabilities: Option[sbt.internal.langserver.ClientCapabilities], trace: Option[String]): InitializeParams = new InitializeParams(processId, rootPath, rootUri, initializationOptions, capabilities, trace)
|
||||
def apply(processId: Long, rootPath: String, rootUri: String, initializationOptions: sjsonnew.shaded.scalajson.ast.unsafe.JValue, capabilities: sbt.internal.langserver.ClientCapabilities, trace: String): InitializeParams = new InitializeParams(Option(processId), Option(rootPath), Option(rootUri), Option(initializationOptions), Option(capabilities), Option(trace))
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver
|
||||
final class InitializeResult private (
|
||||
/** The capabilities the language server provides. */
|
||||
val capabilities: sbt.internal.langserver.ServerCapabilities) extends Serializable {
|
||||
|
||||
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case x: InitializeResult => (this.capabilities == x.capabilities)
|
||||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = {
|
||||
37 * (37 * (17 + "sbt.internal.langserver.InitializeResult".##) + capabilities.##)
|
||||
}
|
||||
override def toString: String = {
|
||||
"InitializeResult(" + capabilities + ")"
|
||||
}
|
||||
protected[this] def copy(capabilities: sbt.internal.langserver.ServerCapabilities = capabilities): InitializeResult = {
|
||||
new InitializeResult(capabilities)
|
||||
}
|
||||
def withCapabilities(capabilities: sbt.internal.langserver.ServerCapabilities): InitializeResult = {
|
||||
copy(capabilities = capabilities)
|
||||
}
|
||||
}
|
||||
object InitializeResult {
|
||||
|
||||
def apply(capabilities: sbt.internal.langserver.ServerCapabilities): InitializeResult = new InitializeResult(capabilities)
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver
|
||||
/** Represents a location inside a resource, such as a line inside a text file. */
|
||||
final class Location private (
|
||||
val uri: String,
|
||||
val range: sbt.internal.langserver.Range) extends Serializable {
|
||||
|
||||
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case x: Location => (this.uri == x.uri) && (this.range == x.range)
|
||||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = {
|
||||
37 * (37 * (37 * (17 + "sbt.internal.langserver.Location".##) + uri.##) + range.##)
|
||||
}
|
||||
override def toString: String = {
|
||||
"Location(" + uri + ", " + range + ")"
|
||||
}
|
||||
protected[this] def copy(uri: String = uri, range: sbt.internal.langserver.Range = range): Location = {
|
||||
new Location(uri, range)
|
||||
}
|
||||
def withUri(uri: String): Location = {
|
||||
copy(uri = uri)
|
||||
}
|
||||
def withRange(range: sbt.internal.langserver.Range): Location = {
|
||||
copy(range = range)
|
||||
}
|
||||
}
|
||||
object Location {
|
||||
|
||||
def apply(uri: String, range: sbt.internal.langserver.Range): Location = new Location(uri, range)
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver
|
||||
/**
|
||||
* Position in a text document expressed as zero-based line and zero-based character offset.
|
||||
* A position is between two characters like an 'insert' cursor in a editor.
|
||||
*/
|
||||
final class Position private (
|
||||
/** Line position in a document (zero-based). */
|
||||
val line: Long,
|
||||
/** Character offset on a line in a document (zero-based). */
|
||||
val character: Long) extends Serializable {
|
||||
|
||||
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case x: Position => (this.line == x.line) && (this.character == x.character)
|
||||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = {
|
||||
37 * (37 * (37 * (17 + "sbt.internal.langserver.Position".##) + line.##) + character.##)
|
||||
}
|
||||
override def toString: String = {
|
||||
"Position(" + line + ", " + character + ")"
|
||||
}
|
||||
protected[this] def copy(line: Long = line, character: Long = character): Position = {
|
||||
new Position(line, character)
|
||||
}
|
||||
def withLine(line: Long): Position = {
|
||||
copy(line = line)
|
||||
}
|
||||
def withCharacter(character: Long): Position = {
|
||||
copy(character = character)
|
||||
}
|
||||
}
|
||||
object Position {
|
||||
|
||||
def apply(line: Long, character: Long): Position = new Position(line, character)
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver
|
||||
/** Diagnostics notification are sent from the server to the client to signal results of validation runs. */
|
||||
final class PublishDiagnosticsParams private (
|
||||
/** The URI for which diagnostic information is reported. */
|
||||
val uri: String,
|
||||
/** An array of diagnostic information items. */
|
||||
val diagnostics: Vector[sbt.internal.langserver.Diagnostic]) extends Serializable {
|
||||
|
||||
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case x: PublishDiagnosticsParams => (this.uri == x.uri) && (this.diagnostics == x.diagnostics)
|
||||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = {
|
||||
37 * (37 * (37 * (17 + "sbt.internal.langserver.PublishDiagnosticsParams".##) + uri.##) + diagnostics.##)
|
||||
}
|
||||
override def toString: String = {
|
||||
"PublishDiagnosticsParams(" + uri + ", " + diagnostics + ")"
|
||||
}
|
||||
protected[this] def copy(uri: String = uri, diagnostics: Vector[sbt.internal.langserver.Diagnostic] = diagnostics): PublishDiagnosticsParams = {
|
||||
new PublishDiagnosticsParams(uri, diagnostics)
|
||||
}
|
||||
def withUri(uri: String): PublishDiagnosticsParams = {
|
||||
copy(uri = uri)
|
||||
}
|
||||
def withDiagnostics(diagnostics: Vector[sbt.internal.langserver.Diagnostic]): PublishDiagnosticsParams = {
|
||||
copy(diagnostics = diagnostics)
|
||||
}
|
||||
}
|
||||
object PublishDiagnosticsParams {
|
||||
|
||||
def apply(uri: String, diagnostics: Vector[sbt.internal.langserver.Diagnostic]): PublishDiagnosticsParams = new PublishDiagnosticsParams(uri, diagnostics)
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver
|
||||
/**
|
||||
* A range in a text document expressed as (zero-based) start and end positions. A range is comparable to a selection in an editor.
|
||||
* Therefore the end position is exclusive.
|
||||
*/
|
||||
final class Range private (
|
||||
/** The range's start position. */
|
||||
val start: sbt.internal.langserver.Position,
|
||||
/** The range's end position. */
|
||||
val end: sbt.internal.langserver.Position) extends Serializable {
|
||||
|
||||
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case x: Range => (this.start == x.start) && (this.end == x.end)
|
||||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = {
|
||||
37 * (37 * (37 * (17 + "sbt.internal.langserver.Range".##) + start.##) + end.##)
|
||||
}
|
||||
override def toString: String = {
|
||||
"Range(" + start + ", " + end + ")"
|
||||
}
|
||||
protected[this] def copy(start: sbt.internal.langserver.Position = start, end: sbt.internal.langserver.Position = end): Range = {
|
||||
new Range(start, end)
|
||||
}
|
||||
def withStart(start: sbt.internal.langserver.Position): Range = {
|
||||
copy(start = start)
|
||||
}
|
||||
def withEnd(end: sbt.internal.langserver.Position): Range = {
|
||||
copy(end = end)
|
||||
}
|
||||
}
|
||||
object Range {
|
||||
|
||||
def apply(start: sbt.internal.langserver.Position, end: sbt.internal.langserver.Position): Range = new Range(start, end)
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver
|
||||
final class SaveOptions private (
|
||||
/** The client is supposed to include the content on save. */
|
||||
val includeText: Option[Boolean]) extends Serializable {
|
||||
|
||||
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case x: SaveOptions => (this.includeText == x.includeText)
|
||||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = {
|
||||
37 * (37 * (17 + "sbt.internal.langserver.SaveOptions".##) + includeText.##)
|
||||
}
|
||||
override def toString: String = {
|
||||
"SaveOptions(" + includeText + ")"
|
||||
}
|
||||
protected[this] def copy(includeText: Option[Boolean] = includeText): SaveOptions = {
|
||||
new SaveOptions(includeText)
|
||||
}
|
||||
def withIncludeText(includeText: Option[Boolean]): SaveOptions = {
|
||||
copy(includeText = includeText)
|
||||
}
|
||||
def withIncludeText(includeText: Boolean): SaveOptions = {
|
||||
copy(includeText = Option(includeText))
|
||||
}
|
||||
}
|
||||
object SaveOptions {
|
||||
|
||||
def apply(includeText: Option[Boolean]): SaveOptions = new SaveOptions(includeText)
|
||||
def apply(includeText: Boolean): SaveOptions = new SaveOptions(Option(includeText))
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver
|
||||
final class ServerCapabilities private (
|
||||
val textDocumentSync: Option[sbt.internal.langserver.TextDocumentSyncOptions],
|
||||
/** The server provides hover support. */
|
||||
val hoverProvider: Option[Boolean]) extends Serializable {
|
||||
|
||||
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case x: ServerCapabilities => (this.textDocumentSync == x.textDocumentSync) && (this.hoverProvider == x.hoverProvider)
|
||||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = {
|
||||
37 * (37 * (37 * (17 + "sbt.internal.langserver.ServerCapabilities".##) + textDocumentSync.##) + hoverProvider.##)
|
||||
}
|
||||
override def toString: String = {
|
||||
"ServerCapabilities(" + textDocumentSync + ", " + hoverProvider + ")"
|
||||
}
|
||||
protected[this] def copy(textDocumentSync: Option[sbt.internal.langserver.TextDocumentSyncOptions] = textDocumentSync, hoverProvider: Option[Boolean] = hoverProvider): ServerCapabilities = {
|
||||
new ServerCapabilities(textDocumentSync, hoverProvider)
|
||||
}
|
||||
def withTextDocumentSync(textDocumentSync: Option[sbt.internal.langserver.TextDocumentSyncOptions]): ServerCapabilities = {
|
||||
copy(textDocumentSync = textDocumentSync)
|
||||
}
|
||||
def withTextDocumentSync(textDocumentSync: sbt.internal.langserver.TextDocumentSyncOptions): ServerCapabilities = {
|
||||
copy(textDocumentSync = Option(textDocumentSync))
|
||||
}
|
||||
def withHoverProvider(hoverProvider: Option[Boolean]): ServerCapabilities = {
|
||||
copy(hoverProvider = hoverProvider)
|
||||
}
|
||||
def withHoverProvider(hoverProvider: Boolean): ServerCapabilities = {
|
||||
copy(hoverProvider = Option(hoverProvider))
|
||||
}
|
||||
}
|
||||
object ServerCapabilities {
|
||||
|
||||
def apply(textDocumentSync: Option[sbt.internal.langserver.TextDocumentSyncOptions], hoverProvider: Option[Boolean]): ServerCapabilities = new ServerCapabilities(textDocumentSync, hoverProvider)
|
||||
def apply(textDocumentSync: sbt.internal.langserver.TextDocumentSyncOptions, hoverProvider: Boolean): ServerCapabilities = new ServerCapabilities(Option(textDocumentSync), Option(hoverProvider))
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver
|
||||
final class TextDocumentSyncOptions private (
|
||||
val openClose: Option[Boolean],
|
||||
val change: Option[Long],
|
||||
val willSave: Option[Boolean],
|
||||
val willSaveWaitUntil: Option[Boolean],
|
||||
val save: Option[sbt.internal.langserver.SaveOptions]) extends Serializable {
|
||||
|
||||
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case x: TextDocumentSyncOptions => (this.openClose == x.openClose) && (this.change == x.change) && (this.willSave == x.willSave) && (this.willSaveWaitUntil == x.willSaveWaitUntil) && (this.save == x.save)
|
||||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = {
|
||||
37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.langserver.TextDocumentSyncOptions".##) + openClose.##) + change.##) + willSave.##) + willSaveWaitUntil.##) + save.##)
|
||||
}
|
||||
override def toString: String = {
|
||||
"TextDocumentSyncOptions(" + openClose + ", " + change + ", " + willSave + ", " + willSaveWaitUntil + ", " + save + ")"
|
||||
}
|
||||
protected[this] def copy(openClose: Option[Boolean] = openClose, change: Option[Long] = change, willSave: Option[Boolean] = willSave, willSaveWaitUntil: Option[Boolean] = willSaveWaitUntil, save: Option[sbt.internal.langserver.SaveOptions] = save): TextDocumentSyncOptions = {
|
||||
new TextDocumentSyncOptions(openClose, change, willSave, willSaveWaitUntil, save)
|
||||
}
|
||||
def withOpenClose(openClose: Option[Boolean]): TextDocumentSyncOptions = {
|
||||
copy(openClose = openClose)
|
||||
}
|
||||
def withOpenClose(openClose: Boolean): TextDocumentSyncOptions = {
|
||||
copy(openClose = Option(openClose))
|
||||
}
|
||||
def withChange(change: Option[Long]): TextDocumentSyncOptions = {
|
||||
copy(change = change)
|
||||
}
|
||||
def withChange(change: Long): TextDocumentSyncOptions = {
|
||||
copy(change = Option(change))
|
||||
}
|
||||
def withWillSave(willSave: Option[Boolean]): TextDocumentSyncOptions = {
|
||||
copy(willSave = willSave)
|
||||
}
|
||||
def withWillSave(willSave: Boolean): TextDocumentSyncOptions = {
|
||||
copy(willSave = Option(willSave))
|
||||
}
|
||||
def withWillSaveWaitUntil(willSaveWaitUntil: Option[Boolean]): TextDocumentSyncOptions = {
|
||||
copy(willSaveWaitUntil = willSaveWaitUntil)
|
||||
}
|
||||
def withWillSaveWaitUntil(willSaveWaitUntil: Boolean): TextDocumentSyncOptions = {
|
||||
copy(willSaveWaitUntil = Option(willSaveWaitUntil))
|
||||
}
|
||||
def withSave(save: Option[sbt.internal.langserver.SaveOptions]): TextDocumentSyncOptions = {
|
||||
copy(save = save)
|
||||
}
|
||||
def withSave(save: sbt.internal.langserver.SaveOptions): TextDocumentSyncOptions = {
|
||||
copy(save = Option(save))
|
||||
}
|
||||
}
|
||||
object TextDocumentSyncOptions {
|
||||
|
||||
def apply(openClose: Option[Boolean], change: Option[Long], willSave: Option[Boolean], willSaveWaitUntil: Option[Boolean], save: Option[sbt.internal.langserver.SaveOptions]): TextDocumentSyncOptions = new TextDocumentSyncOptions(openClose, change, willSave, willSaveWaitUntil, save)
|
||||
def apply(openClose: Boolean, change: Long, willSave: Boolean, willSaveWaitUntil: Boolean, save: sbt.internal.langserver.SaveOptions): TextDocumentSyncOptions = new TextDocumentSyncOptions(Option(openClose), Option(change), Option(willSave), Option(willSaveWaitUntil), Option(save))
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver.codec
|
||||
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||
trait ClientCapabilitiesFormats { self: sjsonnew.BasicJsonProtocol =>
|
||||
implicit lazy val ClientCapabilitiesFormat: JsonFormat[sbt.internal.langserver.ClientCapabilities] = new JsonFormat[sbt.internal.langserver.ClientCapabilities] {
|
||||
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.ClientCapabilities = {
|
||||
jsOpt match {
|
||||
case Some(js) =>
|
||||
unbuilder.beginObject(js)
|
||||
|
||||
unbuilder.endObject()
|
||||
sbt.internal.langserver.ClientCapabilities()
|
||||
case None =>
|
||||
deserializationError("Expected JsObject but found None")
|
||||
}
|
||||
}
|
||||
override def write[J](obj: sbt.internal.langserver.ClientCapabilities, builder: Builder[J]): Unit = {
|
||||
builder.beginObject()
|
||||
|
||||
builder.endObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver.codec
|
||||
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||
trait DiagnosticFormats { self: sbt.internal.langserver.codec.RangeFormats with sjsonnew.BasicJsonProtocol =>
|
||||
implicit lazy val DiagnosticFormat: JsonFormat[sbt.internal.langserver.Diagnostic] = new JsonFormat[sbt.internal.langserver.Diagnostic] {
|
||||
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.Diagnostic = {
|
||||
jsOpt match {
|
||||
case Some(js) =>
|
||||
unbuilder.beginObject(js)
|
||||
val range = unbuilder.readField[sbt.internal.langserver.Range]("range")
|
||||
val severity = unbuilder.readField[Option[Long]]("severity")
|
||||
val code = unbuilder.readField[Option[String]]("code")
|
||||
val source = unbuilder.readField[Option[String]]("source")
|
||||
val message = unbuilder.readField[String]("message")
|
||||
unbuilder.endObject()
|
||||
sbt.internal.langserver.Diagnostic(range, severity, code, source, message)
|
||||
case None =>
|
||||
deserializationError("Expected JsObject but found None")
|
||||
}
|
||||
}
|
||||
override def write[J](obj: sbt.internal.langserver.Diagnostic, builder: Builder[J]): Unit = {
|
||||
builder.beginObject()
|
||||
builder.addField("range", obj.range)
|
||||
builder.addField("severity", obj.severity)
|
||||
builder.addField("code", obj.code)
|
||||
builder.addField("source", obj.source)
|
||||
builder.addField("message", obj.message)
|
||||
builder.endObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver.codec
|
||||
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||
trait InitializeParamsFormats { self: sbt.internal.util.codec.JValueFormats with sbt.internal.langserver.codec.ClientCapabilitiesFormats with sjsonnew.BasicJsonProtocol =>
|
||||
implicit lazy val InitializeParamsFormat: JsonFormat[sbt.internal.langserver.InitializeParams] = new JsonFormat[sbt.internal.langserver.InitializeParams] {
|
||||
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.InitializeParams = {
|
||||
jsOpt match {
|
||||
case Some(js) =>
|
||||
unbuilder.beginObject(js)
|
||||
val processId = unbuilder.readField[Option[Long]]("processId")
|
||||
val rootPath = unbuilder.readField[Option[String]]("rootPath")
|
||||
val rootUri = unbuilder.readField[Option[String]]("rootUri")
|
||||
val initializationOptions = unbuilder.readField[Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]]("initializationOptions")
|
||||
val capabilities = unbuilder.readField[Option[sbt.internal.langserver.ClientCapabilities]]("capabilities")
|
||||
val trace = unbuilder.readField[Option[String]]("trace")
|
||||
unbuilder.endObject()
|
||||
sbt.internal.langserver.InitializeParams(processId, rootPath, rootUri, initializationOptions, capabilities, trace)
|
||||
case None =>
|
||||
deserializationError("Expected JsObject but found None")
|
||||
}
|
||||
}
|
||||
override def write[J](obj: sbt.internal.langserver.InitializeParams, builder: Builder[J]): Unit = {
|
||||
builder.beginObject()
|
||||
builder.addField("processId", obj.processId)
|
||||
builder.addField("rootPath", obj.rootPath)
|
||||
builder.addField("rootUri", obj.rootUri)
|
||||
builder.addField("initializationOptions", obj.initializationOptions)
|
||||
builder.addField("capabilities", obj.capabilities)
|
||||
builder.addField("trace", obj.trace)
|
||||
builder.endObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver.codec
|
||||
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||
trait InitializeResultFormats { self: sbt.internal.langserver.codec.ServerCapabilitiesFormats with sjsonnew.BasicJsonProtocol =>
|
||||
implicit lazy val InitializeResultFormat: JsonFormat[sbt.internal.langserver.InitializeResult] = new JsonFormat[sbt.internal.langserver.InitializeResult] {
|
||||
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.InitializeResult = {
|
||||
jsOpt match {
|
||||
case Some(js) =>
|
||||
unbuilder.beginObject(js)
|
||||
val capabilities = unbuilder.readField[sbt.internal.langserver.ServerCapabilities]("capabilities")
|
||||
unbuilder.endObject()
|
||||
sbt.internal.langserver.InitializeResult(capabilities)
|
||||
case None =>
|
||||
deserializationError("Expected JsObject but found None")
|
||||
}
|
||||
}
|
||||
override def write[J](obj: sbt.internal.langserver.InitializeResult, builder: Builder[J]): Unit = {
|
||||
builder.beginObject()
|
||||
builder.addField("capabilities", obj.capabilities)
|
||||
builder.endObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver.codec
|
||||
trait JsonProtocol extends sjsonnew.BasicJsonProtocol
|
||||
with sbt.internal.langserver.codec.PositionFormats
|
||||
with sbt.internal.langserver.codec.RangeFormats
|
||||
with sbt.internal.langserver.codec.LocationFormats
|
||||
with sbt.internal.langserver.codec.DiagnosticFormats
|
||||
with sbt.internal.util.codec.JValueFormats
|
||||
with sbt.internal.langserver.codec.ClientCapabilitiesFormats
|
||||
with sbt.internal.langserver.codec.InitializeParamsFormats
|
||||
with sbt.internal.langserver.codec.SaveOptionsFormats
|
||||
with sbt.internal.langserver.codec.TextDocumentSyncOptionsFormats
|
||||
with sbt.internal.langserver.codec.ServerCapabilitiesFormats
|
||||
with sbt.internal.langserver.codec.InitializeResultFormats
|
||||
with sbt.internal.langserver.codec.PublishDiagnosticsParamsFormats
|
||||
object JsonProtocol extends JsonProtocol
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver.codec
|
||||
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||
trait LocationFormats { self: sbt.internal.langserver.codec.RangeFormats with sjsonnew.BasicJsonProtocol =>
|
||||
implicit lazy val LocationFormat: JsonFormat[sbt.internal.langserver.Location] = new JsonFormat[sbt.internal.langserver.Location] {
|
||||
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.Location = {
|
||||
jsOpt match {
|
||||
case Some(js) =>
|
||||
unbuilder.beginObject(js)
|
||||
val uri = unbuilder.readField[String]("uri")
|
||||
val range = unbuilder.readField[sbt.internal.langserver.Range]("range")
|
||||
unbuilder.endObject()
|
||||
sbt.internal.langserver.Location(uri, range)
|
||||
case None =>
|
||||
deserializationError("Expected JsObject but found None")
|
||||
}
|
||||
}
|
||||
override def write[J](obj: sbt.internal.langserver.Location, builder: Builder[J]): Unit = {
|
||||
builder.beginObject()
|
||||
builder.addField("uri", obj.uri)
|
||||
builder.addField("range", obj.range)
|
||||
builder.endObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver.codec
|
||||
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||
trait PositionFormats { self: sjsonnew.BasicJsonProtocol =>
|
||||
implicit lazy val PositionFormat: JsonFormat[sbt.internal.langserver.Position] = new JsonFormat[sbt.internal.langserver.Position] {
|
||||
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.Position = {
|
||||
jsOpt match {
|
||||
case Some(js) =>
|
||||
unbuilder.beginObject(js)
|
||||
val line = unbuilder.readField[Long]("line")
|
||||
val character = unbuilder.readField[Long]("character")
|
||||
unbuilder.endObject()
|
||||
sbt.internal.langserver.Position(line, character)
|
||||
case None =>
|
||||
deserializationError("Expected JsObject but found None")
|
||||
}
|
||||
}
|
||||
override def write[J](obj: sbt.internal.langserver.Position, builder: Builder[J]): Unit = {
|
||||
builder.beginObject()
|
||||
builder.addField("line", obj.line)
|
||||
builder.addField("character", obj.character)
|
||||
builder.endObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver.codec
|
||||
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||
trait PublishDiagnosticsParamsFormats { self: sbt.internal.langserver.codec.DiagnosticFormats with sjsonnew.BasicJsonProtocol =>
|
||||
implicit lazy val PublishDiagnosticsParamsFormat: JsonFormat[sbt.internal.langserver.PublishDiagnosticsParams] = new JsonFormat[sbt.internal.langserver.PublishDiagnosticsParams] {
|
||||
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.PublishDiagnosticsParams = {
|
||||
jsOpt match {
|
||||
case Some(js) =>
|
||||
unbuilder.beginObject(js)
|
||||
val uri = unbuilder.readField[String]("uri")
|
||||
val diagnostics = unbuilder.readField[Vector[sbt.internal.langserver.Diagnostic]]("diagnostics")
|
||||
unbuilder.endObject()
|
||||
sbt.internal.langserver.PublishDiagnosticsParams(uri, diagnostics)
|
||||
case None =>
|
||||
deserializationError("Expected JsObject but found None")
|
||||
}
|
||||
}
|
||||
override def write[J](obj: sbt.internal.langserver.PublishDiagnosticsParams, builder: Builder[J]): Unit = {
|
||||
builder.beginObject()
|
||||
builder.addField("uri", obj.uri)
|
||||
builder.addField("diagnostics", obj.diagnostics)
|
||||
builder.endObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver.codec
|
||||
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||
trait RangeFormats { self: sbt.internal.langserver.codec.PositionFormats with sjsonnew.BasicJsonProtocol =>
|
||||
implicit lazy val RangeFormat: JsonFormat[sbt.internal.langserver.Range] = new JsonFormat[sbt.internal.langserver.Range] {
|
||||
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.Range = {
|
||||
jsOpt match {
|
||||
case Some(js) =>
|
||||
unbuilder.beginObject(js)
|
||||
val start = unbuilder.readField[sbt.internal.langserver.Position]("start")
|
||||
val end = unbuilder.readField[sbt.internal.langserver.Position]("end")
|
||||
unbuilder.endObject()
|
||||
sbt.internal.langserver.Range(start, end)
|
||||
case None =>
|
||||
deserializationError("Expected JsObject but found None")
|
||||
}
|
||||
}
|
||||
override def write[J](obj: sbt.internal.langserver.Range, builder: Builder[J]): Unit = {
|
||||
builder.beginObject()
|
||||
builder.addField("start", obj.start)
|
||||
builder.addField("end", obj.end)
|
||||
builder.endObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver.codec
|
||||
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||
trait SaveOptionsFormats { self: sjsonnew.BasicJsonProtocol =>
|
||||
implicit lazy val SaveOptionsFormat: JsonFormat[sbt.internal.langserver.SaveOptions] = new JsonFormat[sbt.internal.langserver.SaveOptions] {
|
||||
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.SaveOptions = {
|
||||
jsOpt match {
|
||||
case Some(js) =>
|
||||
unbuilder.beginObject(js)
|
||||
val includeText = unbuilder.readField[Option[Boolean]]("includeText")
|
||||
unbuilder.endObject()
|
||||
sbt.internal.langserver.SaveOptions(includeText)
|
||||
case None =>
|
||||
deserializationError("Expected JsObject but found None")
|
||||
}
|
||||
}
|
||||
override def write[J](obj: sbt.internal.langserver.SaveOptions, builder: Builder[J]): Unit = {
|
||||
builder.beginObject()
|
||||
builder.addField("includeText", obj.includeText)
|
||||
builder.endObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver.codec
|
||||
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||
trait ServerCapabilitiesFormats { self: sbt.internal.langserver.codec.TextDocumentSyncOptionsFormats with sjsonnew.BasicJsonProtocol =>
|
||||
implicit lazy val ServerCapabilitiesFormat: JsonFormat[sbt.internal.langserver.ServerCapabilities] = new JsonFormat[sbt.internal.langserver.ServerCapabilities] {
|
||||
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.ServerCapabilities = {
|
||||
jsOpt match {
|
||||
case Some(js) =>
|
||||
unbuilder.beginObject(js)
|
||||
val textDocumentSync = unbuilder.readField[Option[sbt.internal.langserver.TextDocumentSyncOptions]]("textDocumentSync")
|
||||
val hoverProvider = unbuilder.readField[Option[Boolean]]("hoverProvider")
|
||||
unbuilder.endObject()
|
||||
sbt.internal.langserver.ServerCapabilities(textDocumentSync, hoverProvider)
|
||||
case None =>
|
||||
deserializationError("Expected JsObject but found None")
|
||||
}
|
||||
}
|
||||
override def write[J](obj: sbt.internal.langserver.ServerCapabilities, builder: Builder[J]): Unit = {
|
||||
builder.beginObject()
|
||||
builder.addField("textDocumentSync", obj.textDocumentSync)
|
||||
builder.addField("hoverProvider", obj.hoverProvider)
|
||||
builder.endObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.langserver.codec
|
||||
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||
trait TextDocumentSyncOptionsFormats { self: sbt.internal.langserver.codec.SaveOptionsFormats with sjsonnew.BasicJsonProtocol =>
|
||||
implicit lazy val TextDocumentSyncOptionsFormat: JsonFormat[sbt.internal.langserver.TextDocumentSyncOptions] = new JsonFormat[sbt.internal.langserver.TextDocumentSyncOptions] {
|
||||
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.TextDocumentSyncOptions = {
|
||||
jsOpt match {
|
||||
case Some(js) =>
|
||||
unbuilder.beginObject(js)
|
||||
val openClose = unbuilder.readField[Option[Boolean]]("openClose")
|
||||
val change = unbuilder.readField[Option[Long]]("change")
|
||||
val willSave = unbuilder.readField[Option[Boolean]]("willSave")
|
||||
val willSaveWaitUntil = unbuilder.readField[Option[Boolean]]("willSaveWaitUntil")
|
||||
val save = unbuilder.readField[Option[sbt.internal.langserver.SaveOptions]]("save")
|
||||
unbuilder.endObject()
|
||||
sbt.internal.langserver.TextDocumentSyncOptions(openClose, change, willSave, willSaveWaitUntil, save)
|
||||
case None =>
|
||||
deserializationError("Expected JsObject but found None")
|
||||
}
|
||||
}
|
||||
override def write[J](obj: sbt.internal.langserver.TextDocumentSyncOptions, builder: Builder[J]): Unit = {
|
||||
builder.beginObject()
|
||||
builder.addField("openClose", obj.openClose)
|
||||
builder.addField("change", obj.change)
|
||||
builder.addField("willSave", obj.willSave)
|
||||
builder.addField("willSaveWaitUntil", obj.willSaveWaitUntil)
|
||||
builder.addField("save", obj.save)
|
||||
builder.endObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.protocol
|
||||
final class InitializeOption private (
|
||||
val token: Option[String]) extends Serializable {
|
||||
|
||||
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case x: InitializeOption => (this.token == x.token)
|
||||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = {
|
||||
37 * (37 * (17 + "sbt.internal.protocol.InitializeOption".##) + token.##)
|
||||
}
|
||||
override def toString: String = {
|
||||
"InitializeOption(" + token + ")"
|
||||
}
|
||||
protected[this] def copy(token: Option[String] = token): InitializeOption = {
|
||||
new InitializeOption(token)
|
||||
}
|
||||
def withToken(token: Option[String]): InitializeOption = {
|
||||
copy(token = token)
|
||||
}
|
||||
def withToken(token: String): InitializeOption = {
|
||||
copy(token = Option(token))
|
||||
}
|
||||
}
|
||||
object InitializeOption {
|
||||
|
||||
def apply(token: Option[String]): InitializeOption = new InitializeOption(token)
|
||||
def apply(token: String): InitializeOption = new InitializeOption(Option(token))
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.protocol
|
||||
/** A general message as defined by JSON-RPC. */
|
||||
abstract class JsonRpcMessage(
|
||||
val jsonrpc: String) extends Serializable {
|
||||
|
||||
|
||||
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case x: JsonRpcMessage => (this.jsonrpc == x.jsonrpc)
|
||||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = {
|
||||
37 * (37 * (17 + "sbt.internal.protocol.JsonRpcMessage".##) + jsonrpc.##)
|
||||
}
|
||||
override def toString: String = {
|
||||
"JsonRpcMessage(" + jsonrpc + ")"
|
||||
}
|
||||
}
|
||||
object JsonRpcMessage {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.protocol
|
||||
final class JsonRpcNotificationMessage private (
|
||||
jsonrpc: String,
|
||||
/** The method to be invoked. */
|
||||
val method: String,
|
||||
/** The method's params. */
|
||||
val params: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]) extends sbt.internal.protocol.JsonRpcMessage(jsonrpc) with Serializable {
|
||||
|
||||
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case x: JsonRpcNotificationMessage => (this.jsonrpc == x.jsonrpc) && (this.method == x.method) && (this.params == x.params)
|
||||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = {
|
||||
37 * (37 * (37 * (37 * (17 + "sbt.internal.protocol.JsonRpcNotificationMessage".##) + jsonrpc.##) + method.##) + params.##)
|
||||
}
|
||||
override def toString: String = {
|
||||
s"""JsonRpcNotificationMessage($jsonrpc, $method, ${sbt.protocol.Serialization.compactPrintJsonOpt(params)})"""
|
||||
}
|
||||
protected[this] def copy(jsonrpc: String = jsonrpc, method: String = method, params: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue] = params): JsonRpcNotificationMessage = {
|
||||
new JsonRpcNotificationMessage(jsonrpc, method, params)
|
||||
}
|
||||
def withJsonrpc(jsonrpc: String): JsonRpcNotificationMessage = {
|
||||
copy(jsonrpc = jsonrpc)
|
||||
}
|
||||
def withMethod(method: String): JsonRpcNotificationMessage = {
|
||||
copy(method = method)
|
||||
}
|
||||
def withParams(params: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]): JsonRpcNotificationMessage = {
|
||||
copy(params = params)
|
||||
}
|
||||
def withParams(params: sjsonnew.shaded.scalajson.ast.unsafe.JValue): JsonRpcNotificationMessage = {
|
||||
copy(params = Option(params))
|
||||
}
|
||||
}
|
||||
object JsonRpcNotificationMessage {
|
||||
|
||||
def apply(jsonrpc: String, method: String, params: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]): JsonRpcNotificationMessage = new JsonRpcNotificationMessage(jsonrpc, method, params)
|
||||
def apply(jsonrpc: String, method: String, params: sjsonnew.shaded.scalajson.ast.unsafe.JValue): JsonRpcNotificationMessage = new JsonRpcNotificationMessage(jsonrpc, method, Option(params))
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.protocol
|
||||
final class JsonRpcRequestMessage private (
|
||||
jsonrpc: String,
|
||||
/** The request id. */
|
||||
val id: String,
|
||||
/** The method to be invoked. */
|
||||
val method: String,
|
||||
/** The method's params. */
|
||||
val params: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]) extends sbt.internal.protocol.JsonRpcMessage(jsonrpc) with Serializable {
|
||||
|
||||
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case x: JsonRpcRequestMessage => (this.jsonrpc == x.jsonrpc) && (this.id == x.id) && (this.method == x.method) && (this.params == x.params)
|
||||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = {
|
||||
37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.protocol.JsonRpcRequestMessage".##) + jsonrpc.##) + id.##) + method.##) + params.##)
|
||||
}
|
||||
override def toString: String = {
|
||||
s"""JsonRpcRequestMessage($jsonrpc, $id, $method, ${sbt.protocol.Serialization.compactPrintJsonOpt(params)}})"""
|
||||
}
|
||||
protected[this] def copy(jsonrpc: String = jsonrpc, id: String = id, method: String = method, params: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue] = params): JsonRpcRequestMessage = {
|
||||
new JsonRpcRequestMessage(jsonrpc, id, method, params)
|
||||
}
|
||||
def withJsonrpc(jsonrpc: String): JsonRpcRequestMessage = {
|
||||
copy(jsonrpc = jsonrpc)
|
||||
}
|
||||
def withId(id: String): JsonRpcRequestMessage = {
|
||||
copy(id = id)
|
||||
}
|
||||
def withMethod(method: String): JsonRpcRequestMessage = {
|
||||
copy(method = method)
|
||||
}
|
||||
def withParams(params: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]): JsonRpcRequestMessage = {
|
||||
copy(params = params)
|
||||
}
|
||||
def withParams(params: sjsonnew.shaded.scalajson.ast.unsafe.JValue): JsonRpcRequestMessage = {
|
||||
copy(params = Option(params))
|
||||
}
|
||||
}
|
||||
object JsonRpcRequestMessage {
|
||||
|
||||
def apply(jsonrpc: String, id: String, method: String, params: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]): JsonRpcRequestMessage = new JsonRpcRequestMessage(jsonrpc, id, method, params)
|
||||
def apply(jsonrpc: String, id: String, method: String, params: sjsonnew.shaded.scalajson.ast.unsafe.JValue): JsonRpcRequestMessage = new JsonRpcRequestMessage(jsonrpc, id, method, Option(params))
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.protocol
|
||||
final class JsonRpcResponseError private (
|
||||
/** A number indicating the error type that occurred. */
|
||||
val code: Long,
|
||||
/** A string providing a short description of the error. */
|
||||
val message: String,
|
||||
/**
|
||||
* A Primitive or Structured value that contains additional
|
||||
* information about the error. Can be omitted.
|
||||
*/
|
||||
val data: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]) extends Serializable {
|
||||
|
||||
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case x: JsonRpcResponseError => (this.code == x.code) && (this.message == x.message) && (this.data == x.data)
|
||||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = {
|
||||
37 * (37 * (37 * (37 * (17 + "sbt.internal.protocol.JsonRpcResponseError".##) + code.##) + message.##) + data.##)
|
||||
}
|
||||
override def toString: String = {
|
||||
s"""JsonRpcResponseError($code, $message, ${sbt.protocol.Serialization.compactPrintJsonOpt(data)})"""
|
||||
}
|
||||
protected[this] def copy(code: Long = code, message: String = message, data: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue] = data): JsonRpcResponseError = {
|
||||
new JsonRpcResponseError(code, message, data)
|
||||
}
|
||||
def withCode(code: Long): JsonRpcResponseError = {
|
||||
copy(code = code)
|
||||
}
|
||||
def withMessage(message: String): JsonRpcResponseError = {
|
||||
copy(message = message)
|
||||
}
|
||||
def withData(data: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]): JsonRpcResponseError = {
|
||||
copy(data = data)
|
||||
}
|
||||
def withData(data: sjsonnew.shaded.scalajson.ast.unsafe.JValue): JsonRpcResponseError = {
|
||||
copy(data = Option(data))
|
||||
}
|
||||
}
|
||||
object JsonRpcResponseError {
|
||||
|
||||
def apply(code: Long, message: String, data: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]): JsonRpcResponseError = new JsonRpcResponseError(code, message, data)
|
||||
def apply(code: Long, message: String, data: sjsonnew.shaded.scalajson.ast.unsafe.JValue): JsonRpcResponseError = new JsonRpcResponseError(code, message, Option(data))
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.protocol
|
||||
final class JsonRpcResponseMessage private (
|
||||
jsonrpc: String,
|
||||
/** The request id. */
|
||||
val id: Option[String],
|
||||
/**
|
||||
* The result of a request. This can be omitted in
|
||||
* the case of an error.
|
||||
*/
|
||||
val result: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue],
|
||||
/** The error object in case a request fails. */
|
||||
val error: Option[sbt.internal.protocol.JsonRpcResponseError]) extends sbt.internal.protocol.JsonRpcMessage(jsonrpc) with Serializable {
|
||||
|
||||
|
||||
|
||||
override def equals(o: Any): Boolean = o match {
|
||||
case x: JsonRpcResponseMessage => (this.jsonrpc == x.jsonrpc) && (this.id == x.id) && (this.result == x.result) && (this.error == x.error)
|
||||
case _ => false
|
||||
}
|
||||
override def hashCode: Int = {
|
||||
37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.protocol.JsonRpcResponseMessage".##) + jsonrpc.##) + id.##) + result.##) + error.##)
|
||||
}
|
||||
override def toString: String = {
|
||||
s"""JsonRpcResponseMessage($jsonrpc, $id, ${sbt.protocol.Serialization.compactPrintJsonOpt(result)}, $error)"""
|
||||
}
|
||||
protected[this] def copy(jsonrpc: String = jsonrpc, id: Option[String] = id, result: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue] = result, error: Option[sbt.internal.protocol.JsonRpcResponseError] = error): JsonRpcResponseMessage = {
|
||||
new JsonRpcResponseMessage(jsonrpc, id, result, error)
|
||||
}
|
||||
def withJsonrpc(jsonrpc: String): JsonRpcResponseMessage = {
|
||||
copy(jsonrpc = jsonrpc)
|
||||
}
|
||||
def withId(id: Option[String]): JsonRpcResponseMessage = {
|
||||
copy(id = id)
|
||||
}
|
||||
def withId(id: String): JsonRpcResponseMessage = {
|
||||
copy(id = Option(id))
|
||||
}
|
||||
def withResult(result: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]): JsonRpcResponseMessage = {
|
||||
copy(result = result)
|
||||
}
|
||||
def withResult(result: sjsonnew.shaded.scalajson.ast.unsafe.JValue): JsonRpcResponseMessage = {
|
||||
copy(result = Option(result))
|
||||
}
|
||||
def withError(error: Option[sbt.internal.protocol.JsonRpcResponseError]): JsonRpcResponseMessage = {
|
||||
copy(error = error)
|
||||
}
|
||||
def withError(error: sbt.internal.protocol.JsonRpcResponseError): JsonRpcResponseMessage = {
|
||||
copy(error = Option(error))
|
||||
}
|
||||
}
|
||||
object JsonRpcResponseMessage {
|
||||
|
||||
def apply(jsonrpc: String, id: Option[String], result: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue], error: Option[sbt.internal.protocol.JsonRpcResponseError]): JsonRpcResponseMessage = new JsonRpcResponseMessage(jsonrpc, id, result, error)
|
||||
def apply(jsonrpc: String, id: String, result: sjsonnew.shaded.scalajson.ast.unsafe.JValue, error: sbt.internal.protocol.JsonRpcResponseError): JsonRpcResponseMessage = new JsonRpcResponseMessage(jsonrpc, Option(id), Option(result), Option(error))
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
|
||||
// DO NOT EDIT MANUALLY
|
||||
package sbt.internal.protocol.codec
|
||||
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||
trait InitializeOptionFormats { self: sjsonnew.BasicJsonProtocol =>
|
||||
implicit lazy val InitializeOptionFormat: JsonFormat[sbt.internal.protocol.InitializeOption] = new JsonFormat[sbt.internal.protocol.InitializeOption] {
|
||||
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.protocol.InitializeOption = {
|
||||
jsOpt match {
|
||||
case Some(js) =>
|
||||
unbuilder.beginObject(js)
|
||||
val token = unbuilder.readField[Option[String]]("token")
|
||||
unbuilder.endObject()
|
||||
sbt.internal.protocol.InitializeOption(token)
|
||||
case None =>
|
||||
deserializationError("Expected JsObject but found None")
|
||||
}
|
||||
}
|
||||
override def write[J](obj: sbt.internal.protocol.InitializeOption, builder: Builder[J]): Unit = {
|
||||
builder.beginObject()
|
||||
builder.addField("token", obj.token)
|
||||
builder.endObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package sbt.internal.protocol
|
||||
@target(Scala)
|
||||
|
||||
## A general message as defined by JSON-RPC.
|
||||
interface JsonRpcMessage
|
||||
@generateCodec(false)
|
||||
{
|
||||
jsonrpc: String!
|
||||
}
|
||||
|
||||
type JsonRpcRequestMessage implements JsonRpcMessage
|
||||
@generateCodec(false)
|
||||
{
|
||||
jsonrpc: String!
|
||||
|
||||
## The request id.
|
||||
id: String!
|
||||
|
||||
## The method to be invoked.
|
||||
method: String!
|
||||
|
||||
## The method's params.
|
||||
params: sjsonnew.shaded.scalajson.ast.unsafe.JValue
|
||||
|
||||
#xtostring s"""JsonRpcRequestMessage($jsonrpc, $id, $method, ${sbt.protocol.Serialization.compactPrintJsonOpt(params)}})"""
|
||||
}
|
||||
|
||||
type JsonRpcResponseMessage implements JsonRpcMessage
|
||||
@generateCodec(false)
|
||||
{
|
||||
jsonrpc: String!
|
||||
|
||||
## The request id.
|
||||
id: String
|
||||
|
||||
## The result of a request. This can be omitted in
|
||||
## the case of an error.
|
||||
result: sjsonnew.shaded.scalajson.ast.unsafe.JValue
|
||||
|
||||
## The error object in case a request fails.
|
||||
error: sbt.internal.protocol.JsonRpcResponseError
|
||||
|
||||
#xtostring s"""JsonRpcResponseMessage($jsonrpc, $id, ${sbt.protocol.Serialization.compactPrintJsonOpt(result)}, $error)"""
|
||||
}
|
||||
|
||||
type JsonRpcResponseError
|
||||
@generateCodec(false)
|
||||
{
|
||||
## A number indicating the error type that occurred.
|
||||
code: Long!
|
||||
|
||||
## A string providing a short description of the error.
|
||||
message: String!
|
||||
|
||||
## A Primitive or Structured value that contains additional
|
||||
## information about the error. Can be omitted.
|
||||
data: sjsonnew.shaded.scalajson.ast.unsafe.JValue
|
||||
|
||||
#xtostring s"""JsonRpcResponseError($code, $message, ${sbt.protocol.Serialization.compactPrintJsonOpt(data)})"""
|
||||
}
|
||||
|
||||
type JsonRpcNotificationMessage implements JsonRpcMessage
|
||||
@generateCodec(false)
|
||||
{
|
||||
jsonrpc: String!
|
||||
|
||||
## The method to be invoked.
|
||||
method: String!
|
||||
|
||||
## The method's params.
|
||||
params: sjsonnew.shaded.scalajson.ast.unsafe.JValue
|
||||
|
||||
#xtostring s"""JsonRpcNotificationMessage($jsonrpc, $method, ${sbt.protocol.Serialization.compactPrintJsonOpt(params)})"""
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
package sbt.internal.langserver
|
||||
@target(Scala)
|
||||
@codecPackage("sbt.internal.langserver.codec")
|
||||
@fullCodec("JsonProtocol")
|
||||
|
||||
# Basic structure
|
||||
|
||||
## Position in a text document expressed as zero-based line and zero-based character offset.
|
||||
## A position is between two characters like an 'insert' cursor in a editor.
|
||||
type Position {
|
||||
## Line position in a document (zero-based).
|
||||
line: Long!
|
||||
|
||||
## Character offset on a line in a document (zero-based).
|
||||
character: Long!
|
||||
}
|
||||
|
||||
## A range in a text document expressed as (zero-based) start and end positions. A range is comparable to a selection in an editor.
|
||||
## Therefore the end position is exclusive.
|
||||
type Range {
|
||||
## The range's start position.
|
||||
start: sbt.internal.langserver.Position!
|
||||
|
||||
## The range's end position.
|
||||
end: sbt.internal.langserver.Position!
|
||||
}
|
||||
|
||||
## Represents a location inside a resource, such as a line inside a text file.
|
||||
type Location {
|
||||
uri: String!
|
||||
range: sbt.internal.langserver.Range!
|
||||
}
|
||||
|
||||
## Represents a diagnostic, such as a compiler error or warning.
|
||||
## Diagnostic objects are only valid in the scope of a resource.
|
||||
type Diagnostic {
|
||||
## The range at which the message applies.
|
||||
range: sbt.internal.langserver.Range!
|
||||
|
||||
## The diagnostic's severity. Can be omitted. If omitted it is up to the
|
||||
## client to interpret diagnostics as error, warning, info or hint.
|
||||
severity: Long
|
||||
|
||||
## The diagnostic's code. Can be omitted.
|
||||
code: String
|
||||
|
||||
## A human-readable string describing the source of this
|
||||
## diagnostic, e.g. 'typescript' or 'super lint'.
|
||||
source: String
|
||||
|
||||
## The diagnostic's message.
|
||||
message: String!
|
||||
}
|
||||
|
||||
# initialize request
|
||||
# https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#initialize-request
|
||||
|
||||
type InitializeParams {
|
||||
processId: Long
|
||||
|
||||
## The rootPath of the workspace.
|
||||
rootPath: String
|
||||
|
||||
rootUri: String
|
||||
|
||||
initializationOptions: sjsonnew.shaded.scalajson.ast.unsafe.JValue
|
||||
|
||||
capabilities: sbt.internal.langserver.ClientCapabilities
|
||||
|
||||
trace: String
|
||||
}
|
||||
|
||||
type ClientCapabilities {
|
||||
}
|
||||
|
||||
type InitializeResult {
|
||||
## The capabilities the language server provides.
|
||||
capabilities: sbt.internal.langserver.ServerCapabilities!
|
||||
}
|
||||
|
||||
type ServerCapabilities {
|
||||
textDocumentSync: sbt.internal.langserver.TextDocumentSyncOptions
|
||||
|
||||
## The server provides hover support.
|
||||
hoverProvider: Boolean
|
||||
}
|
||||
|
||||
type TextDocumentSyncOptions {
|
||||
openClose: Boolean
|
||||
change: Long
|
||||
willSave: Boolean
|
||||
willSaveWaitUntil: Boolean
|
||||
save: sbt.internal.langserver.SaveOptions
|
||||
}
|
||||
|
||||
type SaveOptions {
|
||||
## The client is supposed to include the content on save.
|
||||
includeText: Boolean
|
||||
}
|
||||
|
||||
# Document
|
||||
|
||||
# PublishDiagnostics Notification https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#textDocument_publishDiagnostics
|
||||
|
||||
## Diagnostics notification are sent from the server to the client to signal results of validation runs.
|
||||
type PublishDiagnosticsParams {
|
||||
## The URI for which diagnostic information is reported.
|
||||
uri: String!
|
||||
|
||||
## An array of diagnostic information items.
|
||||
diagnostics: [sbt.internal.langserver.Diagnostic]
|
||||
}
|
||||
|
|
@ -15,3 +15,7 @@ type TokenFile {
|
|||
uri: String!
|
||||
token: String!
|
||||
}
|
||||
|
||||
type InitializeOption {
|
||||
token: String
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
package sbt
|
||||
package internal
|
||||
package langserver
|
||||
|
||||
object DiagnosticSeverity {
|
||||
|
||||
/**
|
||||
* Reports an error.
|
||||
*/
|
||||
val Error = 1L
|
||||
|
||||
/**
|
||||
* Reports a warning.
|
||||
*/
|
||||
val Warning = 2L
|
||||
|
||||
/**
|
||||
* Reports an information.
|
||||
*/
|
||||
val Information = 3L
|
||||
|
||||
/**
|
||||
* Reports a hint.
|
||||
*/
|
||||
val Hint = 4L
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package sbt
|
||||
package internal
|
||||
package langserver
|
||||
|
||||
object ErrorCodes {
|
||||
// Defined by JSON RPC
|
||||
val ParseError = -32700L
|
||||
val InvalidRequest = -32600L
|
||||
val MethodNotFound = -32601L
|
||||
val InvalidParams = -32602L
|
||||
val InternalError = -32603L
|
||||
val serverErrorStart = -32099L
|
||||
val serverErrorEnd = -32000L
|
||||
val ServerNotInitialized = -32002L
|
||||
val UnknownErrorCode = -32001L
|
||||
|
||||
// Defined by the protocol.
|
||||
val RequestCancelled = -32800L
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
package sbt.internal.protocol.codec
|
||||
trait JsonRPCProtocol
|
||||
extends sbt.internal.util.codec.JValueFormats
|
||||
with sjsonnew.BasicJsonProtocol
|
||||
with sbt.internal.protocol.codec.JsonRpcRequestMessageFormats
|
||||
with sbt.internal.protocol.codec.JsonRpcResponseErrorFormats
|
||||
with sbt.internal.protocol.codec.JsonRpcResponseMessageFormats
|
||||
with sbt.internal.protocol.codec.JsonRpcNotificationMessageFormats
|
||||
|
||||
object JsonRPCProtocol extends JsonRPCProtocol
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
package sbt.internal.protocol.codec
|
||||
|
||||
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||
import sjsonnew.shaded.scalajson.ast.unsafe.JValue
|
||||
|
||||
trait JsonRpcNotificationMessageFormats {
|
||||
self: sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol =>
|
||||
implicit lazy val JsonRpcNotificationMessageFormat
|
||||
: JsonFormat[sbt.internal.protocol.JsonRpcNotificationMessage] =
|
||||
new JsonFormat[sbt.internal.protocol.JsonRpcNotificationMessage] {
|
||||
override def read[J](
|
||||
jsOpt: Option[J],
|
||||
unbuilder: Unbuilder[J]): sbt.internal.protocol.JsonRpcNotificationMessage = {
|
||||
jsOpt match {
|
||||
case Some(js) =>
|
||||
unbuilder.beginObject(js)
|
||||
val jsonrpc = unbuilder.readField[String]("jsonrpc")
|
||||
val method = unbuilder.readField[String]("method")
|
||||
val params = unbuilder.lookupField("params") map {
|
||||
case x: JValue => x
|
||||
}
|
||||
unbuilder.endObject()
|
||||
sbt.internal.protocol.JsonRpcNotificationMessage(jsonrpc, method, params)
|
||||
case None =>
|
||||
deserializationError("Expected JsObject but found None")
|
||||
}
|
||||
}
|
||||
override def write[J](obj: sbt.internal.protocol.JsonRpcNotificationMessage,
|
||||
builder: Builder[J]): Unit = {
|
||||
builder.beginObject()
|
||||
builder.addField("jsonrpc", obj.jsonrpc)
|
||||
builder.addField("method", obj.method)
|
||||
builder.addField("params", obj.params)
|
||||
builder.endObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
package sbt.internal.protocol.codec
|
||||
|
||||
import sjsonnew.shaded.scalajson.ast.unsafe.JValue
|
||||
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||
|
||||
trait JsonRpcRequestMessageFormats {
|
||||
self: sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol =>
|
||||
implicit lazy val JsonRpcRequestMessageFormat
|
||||
: JsonFormat[sbt.internal.protocol.JsonRpcRequestMessage] =
|
||||
new JsonFormat[sbt.internal.protocol.JsonRpcRequestMessage] {
|
||||
override def read[J](jsOpt: Option[J],
|
||||
unbuilder: Unbuilder[J]): sbt.internal.protocol.JsonRpcRequestMessage = {
|
||||
jsOpt match {
|
||||
case Some(js) =>
|
||||
unbuilder.beginObject(js)
|
||||
val jsonrpc = unbuilder.readField[String]("jsonrpc")
|
||||
val id = try {
|
||||
unbuilder.readField[String]("id")
|
||||
} catch {
|
||||
case _ => unbuilder.readField[Long]("id").toString
|
||||
}
|
||||
val method = unbuilder.readField[String]("method")
|
||||
val params = unbuilder.lookupField("params") map {
|
||||
case x: JValue => x
|
||||
}
|
||||
unbuilder.endObject()
|
||||
sbt.internal.protocol.JsonRpcRequestMessage(jsonrpc, id, method, params)
|
||||
case None =>
|
||||
deserializationError("Expected JsObject but found None")
|
||||
}
|
||||
}
|
||||
override def write[J](obj: sbt.internal.protocol.JsonRpcRequestMessage,
|
||||
builder: Builder[J]): Unit = {
|
||||
builder.beginObject()
|
||||
builder.addField("jsonrpc", obj.jsonrpc)
|
||||
builder.addField("id", obj.id)
|
||||
builder.addField("method", obj.method)
|
||||
builder.addField("params", obj.params)
|
||||
builder.endObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
package sbt.internal.protocol.codec
|
||||
|
||||
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||
import sjsonnew.shaded.scalajson.ast.unsafe.JValue
|
||||
|
||||
trait JsonRpcResponseErrorFormats {
|
||||
self: sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol =>
|
||||
implicit lazy val JsonRpcResponseErrorFormat
|
||||
: JsonFormat[sbt.internal.protocol.JsonRpcResponseError] =
|
||||
new JsonFormat[sbt.internal.protocol.JsonRpcResponseError] {
|
||||
override def read[J](jsOpt: Option[J],
|
||||
unbuilder: Unbuilder[J]): sbt.internal.protocol.JsonRpcResponseError = {
|
||||
jsOpt match {
|
||||
case Some(js) =>
|
||||
unbuilder.beginObject(js)
|
||||
val code = unbuilder.readField[Long]("code")
|
||||
val message = unbuilder.readField[String]("message")
|
||||
val data = unbuilder.lookupField("data") map {
|
||||
case x: JValue => x
|
||||
}
|
||||
unbuilder.endObject()
|
||||
sbt.internal.protocol.JsonRpcResponseError(code, message, data)
|
||||
case None =>
|
||||
deserializationError("Expected JsObject but found None")
|
||||
}
|
||||
}
|
||||
override def write[J](obj: sbt.internal.protocol.JsonRpcResponseError,
|
||||
builder: Builder[J]): Unit = {
|
||||
builder.beginObject()
|
||||
builder.addField("code", obj.code)
|
||||
builder.addField("message", obj.message)
|
||||
builder.addField("data", obj.data)
|
||||
builder.endObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
|
||||
*/
|
||||
package sbt.internal.protocol.codec
|
||||
|
||||
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
|
||||
import sjsonnew.shaded.scalajson.ast.unsafe.JValue
|
||||
|
||||
trait JsonRpcResponseMessageFormats {
|
||||
self: sbt.internal.util.codec.JValueFormats
|
||||
with sbt.internal.protocol.codec.JsonRpcResponseErrorFormats
|
||||
with sjsonnew.BasicJsonProtocol =>
|
||||
implicit lazy val JsonRpcResponseMessageFormat
|
||||
: JsonFormat[sbt.internal.protocol.JsonRpcResponseMessage] =
|
||||
new JsonFormat[sbt.internal.protocol.JsonRpcResponseMessage] {
|
||||
override def read[J](
|
||||
jsOpt: Option[J],
|
||||
unbuilder: Unbuilder[J]): sbt.internal.protocol.JsonRpcResponseMessage = {
|
||||
jsOpt match {
|
||||
case Some(js) =>
|
||||
unbuilder.beginObject(js)
|
||||
val jsonrpc = unbuilder.readField[String]("jsonrpc")
|
||||
val id = try {
|
||||
unbuilder.readField[Option[String]]("id")
|
||||
} catch {
|
||||
case _ => unbuilder.readField[Option[Long]]("id") map { _.toString }
|
||||
}
|
||||
|
||||
val result = unbuilder.lookupField("result") map {
|
||||
case x: JValue => x
|
||||
}
|
||||
|
||||
val error =
|
||||
unbuilder.readField[Option[sbt.internal.protocol.JsonRpcResponseError]]("error")
|
||||
|
||||
unbuilder.endObject()
|
||||
sbt.internal.protocol.JsonRpcResponseMessage(jsonrpc, id, result, error)
|
||||
case None =>
|
||||
deserializationError("Expected JsObject but found None")
|
||||
}
|
||||
}
|
||||
override def write[J](obj: sbt.internal.protocol.JsonRpcResponseMessage,
|
||||
builder: Builder[J]): Unit = {
|
||||
builder.beginObject()
|
||||
builder.addField("jsonrpc", obj.jsonrpc)
|
||||
builder.addField("id", obj.id)
|
||||
builder.addField("result", obj.result)
|
||||
builder.addField("error", obj.error)
|
||||
builder.endObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,8 +10,15 @@ import sjsonnew.shaded.scalajson.ast.unsafe.{ JValue, JObject, JString }
|
|||
import java.nio.ByteBuffer
|
||||
import scala.util.{ Success, Failure }
|
||||
import sbt.internal.util.StringEvent
|
||||
import sbt.internal.protocol.{
|
||||
JsonRpcRequestMessage,
|
||||
JsonRpcResponseMessage,
|
||||
JsonRpcNotificationMessage
|
||||
}
|
||||
|
||||
object Serialization {
|
||||
private[sbt] val VsCode = "application/vscode-jsonrpc; charset=utf-8"
|
||||
|
||||
def serializeEvent[A: JsonFormat](event: A): Array[Byte] = {
|
||||
val json: JValue = Converter.toJson[A](event).get
|
||||
CompactPrinter(json).getBytes("UTF-8")
|
||||
|
|
@ -29,6 +36,39 @@ object Serialization {
|
|||
CompactPrinter(json).getBytes("UTF-8")
|
||||
}
|
||||
|
||||
/**
|
||||
* This formats the message according to JSON-RPC.
|
||||
* http://www.jsonrpc.org/specification
|
||||
*/
|
||||
private[sbt] def serializeResponseMessage(message: JsonRpcResponseMessage): Array[Byte] = {
|
||||
import sbt.internal.protocol.codec.JsonRPCProtocol._
|
||||
val json: JValue = Converter.toJson[JsonRpcResponseMessage](message).get
|
||||
val body = CompactPrinter(json)
|
||||
val bodyBytes = body.getBytes("UTF-8")
|
||||
|
||||
(s"Content-Length: ${bodyBytes.size}\r\n" +
|
||||
s"Content-Type: $VsCode\r\n" +
|
||||
"\r\n" +
|
||||
body).getBytes("UTF-8")
|
||||
}
|
||||
|
||||
/**
|
||||
* This formats the message according to JSON-RPC.
|
||||
* http://www.jsonrpc.org/specification
|
||||
*/
|
||||
private[sbt] def serializeNotificationMessage(
|
||||
message: JsonRpcNotificationMessage): Array[Byte] = {
|
||||
import sbt.internal.protocol.codec.JsonRPCProtocol._
|
||||
val json: JValue = Converter.toJson[JsonRpcNotificationMessage](message).get
|
||||
val body = CompactPrinter(json)
|
||||
val bodyBytes = body.getBytes("UTF-8")
|
||||
|
||||
(s"Content-Length: ${bodyBytes.size}\r\n" +
|
||||
s"Content-Type: $VsCode\r\n" +
|
||||
"\r\n" +
|
||||
body).getBytes("UTF-8")
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A command or an invalid input description
|
||||
*/
|
||||
|
|
@ -98,4 +138,26 @@ object Serialization {
|
|||
Left(s"Parse error: ${e.getMessage}")
|
||||
}
|
||||
}
|
||||
|
||||
private[sbt] def deserializeJsonRequest(
|
||||
bytes: Seq[Byte]): Either[String, JsonRpcRequestMessage] = {
|
||||
val buffer = ByteBuffer.wrap(bytes.toArray)
|
||||
Parser.parseFromByteBuffer(buffer) match {
|
||||
case Success(json) =>
|
||||
import sbt.internal.protocol.codec.JsonRPCProtocol._
|
||||
Converter.fromJson[JsonRpcRequestMessage](json) match {
|
||||
case Success(msg) => Right(msg)
|
||||
case Failure(e) => throw e
|
||||
}
|
||||
case Failure(e) =>
|
||||
Left(s"Parse error: ${e.getMessage}")
|
||||
}
|
||||
}
|
||||
|
||||
private[sbt] def compactPrintJsonOpt(jsonOpt: Option[JValue]): String = {
|
||||
jsonOpt match {
|
||||
case Some(x) => CompactPrinter(x)
|
||||
case _ => ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,19 +11,25 @@ object Client extends App {
|
|||
val host = "127.0.0.1"
|
||||
val delimiter: Byte = '\n'.toByte
|
||||
|
||||
println("hello")
|
||||
Thread.sleep(1000)
|
||||
lazy val connection = getConnection
|
||||
lazy val out = connection.getOutputStream
|
||||
lazy val in = connection.getInputStream
|
||||
|
||||
val connection = getConnection
|
||||
val out = connection.getOutputStream
|
||||
val in = connection.getInputStream
|
||||
val t = getToken
|
||||
val msg0 = s"""{ "type": "InitCommand", "token": "$t" }"""
|
||||
|
||||
out.write(s"""{ "type": "InitCommand", "token": "$getToken" }""".getBytes("utf-8"))
|
||||
out.write(delimiter.toInt)
|
||||
writeLine(s"Content-Length: ${ msg0.size + 2 }")
|
||||
writeLine("Content-Type: application/sbt-x1")
|
||||
writeLine("")
|
||||
writeLine(msg0)
|
||||
out.flush
|
||||
|
||||
out.write("""{ "type": "ExecCommand", "commandLine": "exit" }""".getBytes("utf-8"))
|
||||
out.write(delimiter.toInt)
|
||||
writeLine("Content-Length: 49")
|
||||
writeLine("Content-Type: application/sbt-x1")
|
||||
writeLine("")
|
||||
// 12345678901234567890123456789012345678901234567890
|
||||
writeLine("""{ "type": "ExecCommand", "commandLine": "exit" }""")
|
||||
writeLine("")
|
||||
out.flush
|
||||
|
||||
val baseDirectory = new File(args(0))
|
||||
|
|
@ -81,4 +87,20 @@ object Client extends App {
|
|||
Thread.sleep(1000)
|
||||
getConnection
|
||||
}
|
||||
|
||||
def writeLine(s: String): Unit = {
|
||||
if (s != "") {
|
||||
out.write(s.getBytes("UTF-8"))
|
||||
}
|
||||
writeEndLine
|
||||
}
|
||||
|
||||
def writeEndLine(): Unit = {
|
||||
val retByte: Byte = '\r'.toByte
|
||||
val delimiter: Byte = '\n'.toByte
|
||||
|
||||
out.write(retByte.toInt)
|
||||
out.write(delimiter.toInt)
|
||||
out.flush
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
> show serverPort
|
||||
> runClient
|
||||
|
||||
-> shell
|
||||
|
||||
$ sleep 1000
|
||||
$ exists ok.txt
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"version": "0.2.0",
|
||||
// List of configurations. Add new configurations or edit existing ones.
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch Client",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceRoot}/client"
|
||||
],
|
||||
"stopOnEntry": false,
|
||||
"sourceMaps": true,
|
||||
"outFiles": [
|
||||
"${workspaceRoot}/client/out/**/*.js"
|
||||
]
|
||||
// "preLaunchTask": "Client Watch"
|
||||
},
|
||||
{
|
||||
"name": "Attach to Server",
|
||||
"type": "node",
|
||||
"request": "attach",
|
||||
"port": 6009,
|
||||
"sourceMaps": true,
|
||||
"outFiles": [
|
||||
"${workspaceRoot}/client/server/**/*.js"
|
||||
],
|
||||
"protocol": "legacy"
|
||||
// "preLaunchTask": "Server Watch"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"files.exclude": {
|
||||
"out": false // set this to true to hide the "out" folder with the compiled JS files
|
||||
},
|
||||
"search.exclude": {
|
||||
"out": true // set this to false to include "out" folder in search results
|
||||
},
|
||||
"typescript.tsdk": "./node_modules/typescript/lib",
|
||||
"typescript.tsc.autoDetect": "off"
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"taskName": "compile",
|
||||
"dependsOn": [
|
||||
"compile:client",
|
||||
"compile:server"
|
||||
],
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "compile:client",
|
||||
"type": "npm",
|
||||
"script": "compile:client",
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"panel": "dedicated",
|
||||
"reveal": "never"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$tsc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "compile:server",
|
||||
"type": "npm",
|
||||
"script": "compile:server",
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"panel": "dedicated",
|
||||
"reveal": "never"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$tsc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"taskName": "watch",
|
||||
"dependsOn": [
|
||||
"watch:client",
|
||||
"watch:server"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "watch:client",
|
||||
"type": "npm",
|
||||
"script": "watch:client",
|
||||
"isBackground": true,
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"panel": "dedicated",
|
||||
"reveal": "never"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$tsc-watch"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "watch:server",
|
||||
"type": "npm",
|
||||
"script": "watch:server",
|
||||
"isBackground": true,
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"panel": "dedicated",
|
||||
"reveal": "never"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$tsc-watch"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
.vscode/**
|
||||
typings/**
|
||||
out/test/**
|
||||
test/**
|
||||
src/**
|
||||
**/*.map
|
||||
.gitignore
|
||||
tsconfig.json
|
||||
vsc-extension-quickstart.md
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
Scala language support using sbt
|
||||
================================
|
||||
|
||||
This is an experimental Scala language support using sbt as the language server.
|
||||
|
||||
To try this, use sbt 1.1.0-M1 and above. Saving `*.scala` will trigger `compile` task.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.6 KiB |
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 43363) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="257.333px" height="147.833px" viewBox="0 0 257.333 147.833" enable-background="new 0 0 257.333 147.833"
|
||||
xml:space="preserve">
|
||||
<g id="guidelines" display="none">
|
||||
<line display="inline" fill="none" stroke="#FF2D00" x1="160.833" y1="21.833" x2="126.958" y2="159.208"/>
|
||||
<line display="inline" fill="none" stroke="#FF2D00" x1="181.25" y1="28.875" x2="147.375" y2="166.25"/>
|
||||
</g>
|
||||
<g id="Layer_3">
|
||||
<path fill="#380D09" d="M17.417,106.458l-13.25,12c0,0,6.5,8.125,15.125,13s13.381,4.508,23.065,4.379
|
||||
c9.31,0,18.81-1.754,26.435-8.504s9.066-8.6,9.033-17.112c-0.016-3.994-1.075-12.813-5.908-18.513
|
||||
c-5.466-6.445-14.781-9.566-14.781-9.566s-28.53-7.155-25.594-17.059c1.232-4.156,7.818-5.726,14.292-4.583
|
||||
c8.192,1.444,16.474,6.371,16.474,6.371l11.577-11.33c0,0-5.274-6.198-13.468-10.208c-6.064-2.967-14.428-4.059-19.783-4.078
|
||||
c-12.592-0.047-28.335,11.197-30.217,22.828c-1.375,8.5,1.383,15.676,7.625,21.125c7.875,6.875,13.478,7.771,13.478,7.771
|
||||
s25.123,6.469,25.123,14.286s-6.101,10.692-15.851,10.817S17.417,106.458,17.417,106.458z"/>
|
||||
<path fill="#380D09" d="M198.508,45.484l0.2,18.199h10.4l0.1,53.9c0,0,1.801,6.2,6.5,10.8c6.065,5.937,12.4,7.454,12.4,7.454
|
||||
h20.399l0.101-18.554l-11-0.1c0,0-2.401,0.101-5.1-2.5c-2.801-2.7-2.7-6.2-2.7-6.2l0.2-44.9h20l0.1-18.2l-20-0.1l-0.2-35.2h-20.8
|
||||
l0.2,35.4H198.508z"/>
|
||||
<path fill="#380D09" d="M156.667,49.833c-12.529-2.767-25.25-1.375-33.375,3.375l10.625-43.125l-21.188-5.188L82.604,126.333
|
||||
l21,6.062L106.5,120.5c6.167,11.666,13.194,17.279,26.667,20.333c25,5.667,47.312-11.762,53.334-38.667
|
||||
C191.667,79.083,175.917,54.083,156.667,49.833z M162.756,117.094l-30.152,8.302l-22.49-22.776l7.666-31.077l30.155-8.302
|
||||
l22.487,22.776L162.756,117.094z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"name": "vscode-sbt-scala",
|
||||
"displayName": "Scala (sbt)",
|
||||
"version": "0.0.1",
|
||||
"author": "Lightbend, Inc.",
|
||||
"license": "BSD-3-Clause",
|
||||
"publisher": "lightbend",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sbt/sbt"
|
||||
},
|
||||
"description": "Scala language support using sbt",
|
||||
"icon": "images/sbt-logo-455x262.png",
|
||||
"engines": {
|
||||
"vscode": "^1.16.0"
|
||||
},
|
||||
"categories": [
|
||||
"Languages"
|
||||
],
|
||||
"activationEvents": [
|
||||
"workspaceContains:build.sbt"
|
||||
],
|
||||
"main": "./out/src/extension",
|
||||
"scripts": {
|
||||
"vscode:prepublish": "tsc -p ./",
|
||||
"compile": "tsc -p ./",
|
||||
"watch": "tsc -w -p ./",
|
||||
"update-vscode": "node ./node_modules/vscode/bin/install",
|
||||
"postinstall": "node ./node_modules/vscode/bin/install"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode": "^1.1.5",
|
||||
"vscode-languageclient": "^3.4.2"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
'use strict';
|
||||
|
||||
import * as path from 'path';
|
||||
|
||||
let fs = require('fs');
|
||||
import { ExtensionContext, workspace } from 'vscode'; // workspace,
|
||||
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient';
|
||||
|
||||
export function activate(context: ExtensionContext) {
|
||||
// The server is implemented in node
|
||||
let serverModule = context.asAbsolutePath(path.join('server', 'server.js'));
|
||||
// The debug options for the server
|
||||
// let debugOptions = { execArgv: ["--nolazy", "--debug=6009"] };
|
||||
|
||||
// If the extension is launched in debug mode then the debug server options are used
|
||||
// Otherwise the run options are used
|
||||
let serverOptions: ServerOptions = {
|
||||
run : { module: serverModule, transport: TransportKind.stdio },
|
||||
debug: { module: serverModule, transport: TransportKind.stdio }
|
||||
}
|
||||
|
||||
// Options to control the language client
|
||||
let clientOptions: LanguageClientOptions = {
|
||||
documentSelector: [{ language: 'scala', scheme: 'file' }, { language: 'java', scheme: 'file' }],
|
||||
initializationOptions: () => {
|
||||
return {
|
||||
token: discoverToken()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// the port file is hardcoded to a particular location relative to the build.
|
||||
function discoverToken(): String {
|
||||
let pf = path.join(workspace.rootPath, 'project', 'target', 'active.json');
|
||||
let portfile = JSON.parse(fs.readFileSync(pf));
|
||||
let tf = portfile.tokenfilePath;
|
||||
let tokenfile = JSON.parse(fs.readFileSync(tf));
|
||||
return tokenfile.token;
|
||||
}
|
||||
|
||||
// Create the language client and start the client.
|
||||
let disposable = new LanguageClient('lspSbtScala', 'sbt Scala Language Server', serverOptions, clientOptions).start();
|
||||
|
||||
context.subscriptions.push(disposable);
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"rootDir": ".",
|
||||
"outDir": "out",
|
||||
"lib": [ "es2016" ],
|
||||
"sourceMap": true
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"server"
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "vscode-sbt-scala",
|
||||
"version": "0.0.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@types/mocha": {
|
||||
"version": "2.2.43",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.43.tgz",
|
||||
"integrity": "sha512-xNlAmH+lRJdUMXClMTI9Y0pRqIojdxfm7DHsIxoB2iTzu3fnPmSMEN8SsSx0cdwV36d02PWCWaDUoZPDSln+xw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "6.0.88",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.88.tgz",
|
||||
"integrity": "sha512-bYDPZTX0/s1aihdjLuAgogUAT5M+TpoWChEMea2p0yOcfn5bu3k6cJb9cp6nw268XeSNIGGr+4+/8V5K6BGzLQ==",
|
||||
"dev": true
|
||||
},
|
||||
"typescript": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.5.2.tgz",
|
||||
"integrity": "sha1-A4qV99m7tCCxvzW6MdTFwd0//jQ=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "vscode-sbt-scala",
|
||||
"displayName": "Scala (sbt)",
|
||||
"version": "0.0.1",
|
||||
"author": "Lightbend, Inc.",
|
||||
"license": "BSD-3-Clause",
|
||||
"publisher": "lightbend",
|
||||
"description": "Scala language support for Visual Studio Code using sbt",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sbt/sbt"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "cd server && npm install && cd ../client && npm install && cd ..",
|
||||
"compile": "tsc -p client/tsconfig.json && cd server && npm run installServer && cd .. && tsc -p server/tsconfig.json",
|
||||
"compile:client": "tsc -p client/tsconfig.json",
|
||||
"watch:client": "tsc -w -p client/tsconfig.json",
|
||||
"compile:server": "cd server && npm run installServer && cd .. && tsc -p server/tsconfig.json",
|
||||
"watch:server": "cd server && npm run installServer && cd .. && tsc -w -p server/tsconfig.json"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^2.2.42",
|
||||
"@types/node": "^6.0.88",
|
||||
"typescript": "^2.5.2"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"name": "vscode-sbt-scala",
|
||||
"version": "0.0.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"vscode-jsonrpc": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.4.0.tgz",
|
||||
"integrity": "sha1-qpWsWDvzHYD3JdV8J8CfTCz+n6k="
|
||||
},
|
||||
"vscode-languageserver": {
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-3.4.2.tgz",
|
||||
"integrity": "sha1-CMvlDuJpAdN91LXcUsJbkJNjwfE=",
|
||||
"requires": {
|
||||
"vscode-languageserver-protocol": "3.4.1",
|
||||
"vscode-uri": "1.0.1"
|
||||
}
|
||||
},
|
||||
"vscode-languageserver-protocol": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.4.1.tgz",
|
||||
"integrity": "sha1-lrfIo+1opOvTCkB7BCenY3k1/h8=",
|
||||
"requires": {
|
||||
"vscode-jsonrpc": "3.4.0",
|
||||
"vscode-languageserver-types": "3.4.0"
|
||||
}
|
||||
},
|
||||
"vscode-languageserver-types": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.4.0.tgz",
|
||||
"integrity": "sha1-UEOuR+5KwWrwe7PQylYSNeDA0vo="
|
||||
},
|
||||
"vscode-uri": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.1.tgz",
|
||||
"integrity": "sha1-Eahr7+rDxKo+wIYjZRo8gabQu8g="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"name": "vscode-sbt-scala",
|
||||
"displayName": "Scala (sbt)",
|
||||
"version": "0.0.1",
|
||||
"author": "Lightbend, Inc.",
|
||||
"license": "BSD-3-Clause",
|
||||
"publisher": "lightbend",
|
||||
"description": "Relay server to sbt server.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sbt/sbt"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-languageserver": "^3.4.2"
|
||||
},
|
||||
"scripts": {
|
||||
"installServer": "installServerIntoExtension ../client ./package.json ./tsconfig.json",
|
||||
"compile": "installServerIntoExtension ../client ./package.json ./tsconfig.json && tsc -p .",
|
||||
"watch": "installServerIntoExtension ../client ./package.json ./tsconfig.json && tsc -w -p ."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
'use strict';
|
||||
|
||||
import * as path from 'path';
|
||||
import * as url from 'url';
|
||||
let net = require('net'),
|
||||
fs = require('fs'),
|
||||
stdin = process.stdin,
|
||||
stdout = process.stdout;
|
||||
|
||||
let u = discoverUrl();
|
||||
|
||||
let socket = net.Socket();
|
||||
socket.on('data', (chunk: any) => {
|
||||
// send it back to stdout
|
||||
stdout.write(chunk);
|
||||
}).on('end', () => {
|
||||
stdin.pause();
|
||||
});
|
||||
socket.connect(u.port, '127.0.0.1');
|
||||
|
||||
stdin.resume();
|
||||
stdin.on('data', (chunk: any) => {
|
||||
socket.write(chunk);
|
||||
}).on('end', () => {
|
||||
socket.end();
|
||||
});
|
||||
|
||||
// the port file is hardcoded to a particular location relative to the build.
|
||||
function discoverUrl(): url.Url {
|
||||
let pf = path.join(process.cwd(), 'project', 'target', 'active.json');
|
||||
let portfile = JSON.parse(fs.readFileSync(pf));
|
||||
return url.parse(portfile.uri);
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"lib" : [ "es2016" ],
|
||||
"outDir": "../client/server"
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
Loading…
Reference in New Issue