-
Notifications
You must be signed in to change notification settings - Fork 352
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Go to definition in classpath #23
Changes from all commits
ab517c3
6547cf3
eebbe39
445e332
062f8e9
cc537c5
766361a
864821d
4b175b9
6ad69f0
bf1b6f9
420f11d
e64a505
5c7951a
bcd3905
01f51b3
db1779a
3de1c85
da8e1d8
dca5a4a
2d09433
a85dbaf
fe8cfa4
12a4a64
0b29617
d05108d
c2cb7bd
020faaa
81b8520
dc03def
ed8e327
fd2035a
50191c1
3576919
5e9272f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ case "$TEST" in | |
./scalafmt --test | ||
;; | ||
* ) | ||
sbt metaserver/compile | ||
sbt test | ||
;; | ||
esac | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package org.langmeta.languageserver | ||
|
||
import org.langmeta.inputs.Input | ||
import org.langmeta.inputs.Position | ||
|
||
object InputEnrichments { | ||
implicit class XtensionInputOffset(val input: Input) extends AnyVal { | ||
|
||
/** Returns an offset for this input */ | ||
def toOffset(line: Int, column: Int): Int = | ||
input.lineToOffset(line) + column | ||
|
||
/** Returns an offset position for this input */ | ||
def toPosition(startLine: Int, startColumn: Int): Position.Range = | ||
toPosition(startLine, startColumn, startLine, startColumn) | ||
|
||
/** Returns a range position for this input */ | ||
def toPosition( | ||
startLine: Int, | ||
startColumn: Int, | ||
endLine: Int, | ||
endColumn: Int | ||
): Position.Range = | ||
Position.Range( | ||
input, | ||
toOffset(startLine, startColumn), | ||
toOffset(endLine, endColumn) | ||
) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package scala.meta.languageserver | ||
|
||
import java.io.File | ||
import java.nio.file.Files | ||
import java.nio.file.Paths | ||
import java.util.Properties | ||
import com.typesafe.scalalogging.LazyLogging | ||
import org.langmeta.io.AbsolutePath | ||
import org.langmeta.io.Classpath | ||
|
||
/** | ||
* Configuration to load up a presentation compiler. | ||
* | ||
* In sbt, one compiler config typically corresponds to one project+config. | ||
* For example one sbt project with test/main/it configurations has three | ||
* CompilerConfig. | ||
* | ||
* @param sources list of source files for this project | ||
* @param scalacOptions space separated list of flags to pass to the Scala compiler | ||
* @param dependencyClasspath File.pathSeparated list of *.jar and classDirectories. | ||
* Includes both dependencyClasspath and classDirectory. | ||
* @param classDirectory The output directory where *.class files are emitted | ||
* for this project. | ||
* @param sourceJars File.pathSeparated list of *-sources.jar from the | ||
* dependencyClasspath. | ||
*/ | ||
case class CompilerConfig( | ||
sources: List[AbsolutePath], | ||
scalacOptions: List[String], | ||
classDirectory: AbsolutePath, | ||
dependencyClasspath: List[AbsolutePath], | ||
sourceJars: List[AbsolutePath] | ||
) { | ||
override def toString: String = | ||
s"CompilerConfig(" + | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since we have pprint as a dependency, you can probably just do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can't find |
||
s"sources={+${sources.length}}, " + | ||
s"scalacOptions=${scalacOptions.mkString(" ")}, " + | ||
s"dependencyClasspath={+${dependencyClasspath.length}}, " + | ||
s"classDirectory=$classDirectory, " + | ||
s"sourceJars={+${sourceJars.length}})" | ||
def classpath: String = | ||
(classDirectory :: dependencyClasspath).mkString(File.pathSeparator) | ||
} | ||
|
||
object CompilerConfig extends LazyLogging { | ||
|
||
def jdkSourcePath: Option[AbsolutePath] = | ||
sys.env.get("JAVA_HOME").map(AbsolutePath(_).resolve("src.zip")) | ||
|
||
def jdkSources: Option[AbsolutePath] = | ||
for { | ||
path <- jdkSourcePath | ||
if Files.isRegularFile(path.toNIO) | ||
} yield path | ||
|
||
def fromPath( | ||
path: AbsolutePath | ||
)(implicit cwd: AbsolutePath): CompilerConfig = { | ||
val input = Files.newInputStream(path.toNIO) | ||
try { | ||
val props = new Properties() | ||
props.load(input) | ||
fromProperties(props) | ||
} finally input.close() | ||
} | ||
|
||
def fromProperties( | ||
props: Properties | ||
)(implicit cwd: AbsolutePath): CompilerConfig = { | ||
val sources = props | ||
.getProperty("sources") | ||
.split(File.pathSeparator) | ||
.iterator | ||
.map(AbsolutePath(_)) | ||
.toList | ||
val scalacOptions = | ||
props.getProperty("scalacOptions").split(" ").toList | ||
val dependencyClasspath = | ||
Classpath(props.getProperty("dependencyClasspath")).shallow | ||
val sourceJars = { | ||
val result = Classpath(props.getProperty("sourceJars")).shallow | ||
jdkSources.fold(result)(_ :: result) | ||
} | ||
val classDirectory = | ||
AbsolutePath(props.getProperty("classDirectory")) | ||
CompilerConfig( | ||
sources, | ||
scalacOptions, | ||
classDirectory, | ||
dependencyClasspath, | ||
sourceJars | ||
) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package scala.meta.languageserver | ||
|
||
/** | ||
* The ScalametaLanguageServer effects. | ||
* | ||
* Observable[Unit] is not descriptive of what the observable represents. | ||
* Instead, we create Unit-like types to better document what effects are | ||
* flowing through our application. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Love this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Poor man's type-safety. I refactored to this in fact because I hit on bugs related to accidentally creating There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. are these phantom types? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not really since those values also exist at runtime. I'm still not sure if this was necessary, maybe we can avoid it by using stricter scalac options (no discard unit). However, I think it's a nice replacement for |
||
*/ | ||
sealed abstract class Effects | ||
object Effects { | ||
final class IndexSemanticdb extends Effects | ||
final val IndexSemanticdb = new IndexSemanticdb | ||
final class IndexSourcesClasspath extends Effects | ||
final val IndexSourcesClasspath = new IndexSourcesClasspath | ||
final class InstallPresentationCompiler extends Effects | ||
final val InstallPresentationCompiler = new InstallPresentationCompiler | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we using IO and NIO?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
java.io is only for
File.pathSeparator
, otherwise we use nio for I/O workThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIO Filesystem has a platform independent separator if you want to stick with the NIO api.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I prefer java.io.File.pathSeparator over FileSystems.getDefault.getSeparator