-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Snippet compiler #11582
Snippet compiler #11582
Conversation
target: AbstractFile = new VirtualDirectory("(memory)") | ||
): | ||
|
||
private def newDriver: InteractiveDriver = { |
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.
In future we can probably stop after the given phases since we probably do not need to produce bytecode.
|
||
def compile( | ||
snippets: List[String] | ||
): Either[SnippetCompilerException, AbstractFile] = { |
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.
What about warning from successfull compilation?
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 guess we will need to return something like SnippetCompilationResult
:
case class SnippetCompilationResult(result: Option[AbstractFile], messages: Seq[SnippetCompilerMessage])
): | ||
def checkSnippet(snippet: String) = { | ||
val wrapped = wrapper.wrap(snippet) | ||
compiler.compile(snippet) |
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.
we should compile wrapped, shouldn't we?
46208b0
to
a8a39f8
Compare
853317f
to
04ec4cb
Compare
private val sep = System.getProperty("path.separator") | ||
private val cp = System.getProperty("java.class.path") + sep + | ||
Paths.get(ctx.args.classpath).toAbsolutePath + sep + | ||
ctx.args.tastyDirs.map(_.getAbsolutePath()).mkString(sep) |
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.
(Seq(System.getProperty("java.class.path"), Paths.get(ctx.args.classpath).toAbsolutePath) ++
ctx.args.tastyDirs.map(_.getAbsolutePath())).mkString(sep)
} | ||
|
||
def summary: String = s""" | ||
|Snippet compiler summary: |
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.
formatting is strange
ctx.args.tastyDirs.map(_.getAbsolutePath()).mkString(sep) | ||
private val compiler: SnippetCompiler = SnippetCompiler(classpath = cp) | ||
private val wrapper: SnippetWrapper = SnippetWrapper() | ||
var warningsCount = 0 |
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.
it should be private
package dotty.tools.scaladoc | ||
package snippets | ||
|
||
import dotty.tools.io.{ AbstractFile } |
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.
remove braces
import dotty.tools.dotc.interfaces.Diagnostic._ | ||
|
||
class SnippetCompiler( | ||
classpath: String = System.getProperty("java.class.path"), //Probably needs to be done better |
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.
Do we need that default here? it looks a bit denegerous.
70d5815
to
61a74c5
Compare
Hey @pikinier20, is this PR ready to be reviewed again? |
Yes, it is, apart from the fact that I need to resolve conflicts. |
case MessageLevel.Error => "snippet-error" | ||
case MessageLevel.Debug => "snippet-debug" | ||
|
||
private def cutBetwenSymbols[A]( |
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.
private def cutBetwenSymbols[A]( | |
private def cutBetweenSymbols[A]( |
e3f171a
to
2d4e88b
Compare
799e543
to
2d1d670
Compare
project/Build.scala
Outdated
// TODO add versions etc. | ||
def srcManaged(v: String, s: String) = s"out/bootstrap/stdlib-bootstrapped/scala-$v/src_managed/main/$s-library-src" | ||
def scalaSrcLink(v: String, s: String) = s"-source-links:$s=github://scala/scala/v$v#src/library" | ||
def dottySrcLink(v: String, s: String) = s"-source-links:$s=github://lampepfl/dotty/$v#library/src" | ||
def bootclasspath: Seq[String] = if(addBootclasspath) Seq( | ||
"-bootclasspath", |
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 do you need a separate bootclasspath given these libraries will be on the classpath anyway?
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.
We need to somehow pass path to standard library to the snippet compiler, otherwise we get MissingCoreLibraryException
. I've seen that sbt in task doc
automatically passes this path in bootclasspath
arg so I added support for this arg in scaladoc. Then I realized that in our sbt project we don't pass explicit bootclasspath to generateDocumentation
task and snippet compiler didn't work. Previously I wanted to just pass System.getProperty("java.class.path")
but it led to errors because we got sbt libs on classpath.
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.
OK, but you should be able to use the regular -classpath and not necessarily -bootclasspath (which isn't really needed anymore)
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.
But -classpath
doesn't contain or at least it didn't contain stdlib entry when this was implemented and without stdlib entry I can't instantiate Context. Or maybe is there other way to obtain path to stdlib?
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.
Which -classpath? It looks like -classpath isn't passed at all to scaladoc here, so I was just suggesting using that instead of -bootclasspath to pass the stdlib
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.
Actually maybe the issue is in the scaladoc shell script? Unlike the scalac shell scrpt it doesn't pass the -Dscala.usejavacp=true
flag so that the JVM classpath is available to the compiler: https://github.com/lampepfl/dotty/blob/83e17f110bfaa2fe876bacc90eca208f23930f98/dist/bin/scalac#L77-L78 vs https://github.com/lampepfl/dotty/blob/83e17f110bfaa2fe876bacc90eca208f23930f98/dist/bin/scaladoc#L129
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.
that's a good point, gonna check that
MultiStringSetting("-snippet-compiler", "snippet-compiler", snippets.SnippetCompilerArgs.usage) | ||
|
||
val snippetCompilerDebug: Setting[Boolean] = | ||
BooleanSetting("-snippet-compiler-debug", snippets.SnippetCompilerArgs.debugUsage, false) |
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.
Flags which are for debugging purpose only and not intended for others to use should start with -Y
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 wasn't aware of this. Thanks!
lazy val snippetChecker = snippets.SnippetChecker( | ||
args.classpath, | ||
args.bootclasspath, | ||
args.tastyFiles, | ||
compilerContext.settings.scalajs.value(using compilerContext), | ||
compilerContext.settings.usejavacp.value(using compilerContext) | ||
) |
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.
There might be more settings needed to compile snippets (for example, if a compiler plugin is used), and adding them one by one isn't going to scale, could you pass all of compilerContext.settings instead?
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.
Yes, you're right and ofc I can do that, but I'm afraid of passing options that can totally break snippet compiler. I don't have knowledge of all possible settings but e.g. what will the compiler do with -from-tasty
setting?
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.
what will the compiler do with -from-tasty setting?
It will unpickle the .tasty files and compile them to .class files.
6c1086c
to
01dacd4
Compare
dist/bin/scaladoc
Outdated
@@ -127,7 +127,6 @@ eval "\"$JAVACMD\"" \ | |||
${JAVA_OPTS:-$default_java_opts} \ | |||
"${java_args[@]}" \ | |||
"${jvm_cp_args-}" \ | |||
-Dscala.usejavacp=true \ |
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.
Any particular reason for removing this flag? It's in dist/bin/scala and dist/bin/scalac, so it makes sense to have it here too.
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.
Yes, I removed this flag intentionally. It helped me a lot and made most of things working but then I realized that with this flag set, generating standard library documentation is failing. I'm not sure about the exact reason but I believe it's because we've got then two standard libraries on classpath and there was some conflict between them. Instead of setting the flag there, I set it directly in tasks that needed it.
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.
Ok, but that means the scaladoc binary isn't really usable for external users. I believe the best solution is to not call the scaladoc script from Build.scala at all. Instead you should be able to run the scaladoc main class from the sbt project directly: (Compile / runMain).toTask("-foo -bla -bar")
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.
Caution ! scaladoc binary MUST BE usable for external users, as are javadoc
and haddock
for instance.
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.
So probably I need to implement @smarter solution. The funny part is that the -usejavacp option is not there on master, I added it some commits before in this PR, but now I realized it breaks doc generation for one task.
Also, can you provide me more information about usage of this binary? Let's say I've got a example scala3 project and I want to call scaladoc on it without sbt. Where should I look for binary and how to use it?
private val snippetCompilerSettings: Seq[SnippetCompilerSetting[_]] = cctx.settings.userSetSettings(cctx.settingsState).filter(_ != cctx.settings.classpath).map( s => | ||
SnippetCompilerSetting(s, s.valueIn(cctx.settingsState)) | ||
) :+ SnippetCompilerSetting(cctx.settings.classpath, fullClasspath) |
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.
What is the purpose of SnippetCompilerSetting? If it's just storing settings it seems that the existing SettingsState
would suffice and you could write something like :
private val snippetCompilerSettings = cctx.settings.classpath.updateIn(cctx.settingsState, fullClasspath)
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.
If we change classpath of compiler context used to load TASTY to produce documentation from, won't it affect loading process?
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.
Since updateIn returns a new SettingsState, I was expecting it to not mutate the existing settingsState of the compiler context, but in fact it's slightly more tricky than that, it will be mutated if no one tried to read a setting previously: https://github.com/lampepfl/dotty/blob/e2e77b56d012b00faf16a86ad1c8437404bb0812/compiler/src/dotty/tools/dotc/config/Settings.scala#L36-L40 (this is a really bad idea and that code that should be replaced)
rootCtx.setSetting(rootCtx.settings.YretainTrees, true) | ||
rootCtx.setSetting(rootCtx.settings.YcookComments, true) | ||
rootCtx.setSetting(rootCtx.settings.YreadComments, true) | ||
val defaultFlags = | ||
List("-color:never", "-unchecked", "-deprecation", "-Ximport-suggestion-timeout", "0") |
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.
Some settings are set with setSetting
and some are strings passed to setup
, it would be nicer and more type-safe to always use setSetting
:
rootCtx.setSetting(rootCtx.settings.color, "never")
.setSetting(...) // etc
Also it seems weird to explicitly enable -unchecked
and -deprecation
here, why those settings in particular? If the user wants them they can add them in scalacOptions
themselves.
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.
The reason behind exactly these flags is that mdoc uses them. But I think it's OK to remove them and let user choose.
…t scaladoc compiler
…o generateDocumentation task
5c7a83d
to
263b484
Compare
@@ -1243,7 +1243,7 @@ object Build { | |||
libraryDependencies += ("org.scala-js" %%% "scalajs-dom" % "1.1.0").cross(CrossVersion.for3Use2_13) | |||
) | |||
|
|||
def generateDocumentation(targets: Seq[String], name: String, outDir: String, ref: String, params: Seq[String] = Nil) = | |||
def generateDocumentation(targets: Seq[String], name: String, outDir: String, ref: String, params: Seq[String] = Nil, usingScript: Boolean = true) = |
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.
This can be fixed later but do you know why we need usingScript in some situations and couldn't just always use Compile/run ?
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.
It was my idea to have some coverage for scripts. Beside that there are no blockers to switch all cases to running Compile/run
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 see, for consistency I suggest always using Compile/run and instead test the scaladoc binary from https://github.com/lampepfl/dotty/blob/master/project/scripts/cmdTests
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.
@pikinier20 can we change that in follow up PR?
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.
@pikinier20 can we change that in follow up PR?
Sure
263b484
to
946752f
Compare
No description provided.