This commit does some changes to the implementation with the purpose of
making this code more readable. I find that this rewrite was necessary
as I was implementing the dependency lock file.
This commit has two goals:
* Simplify the `load` API endpoints, removing the unused ones to shorten
the surface of the API.
* Add documentation to the main `load` methods.
Sbt has a feature to show timed logs for every operation at startup.
However, its output is cluttered and users cannot read how much time
single methods consume nor if they call other methods.
This commit improves the status quo by adding indentation.
This commit reduces the complexity around `loadPluginDefinition` et al.
`pluginDefinitionLoader` is not used anywhere in sbt, so the extra
definitions are removed.
Both the implementation of `loadPluginDefinition` and
`pluginDefinitionLoader` are reduced to a bare minimum where the
components at hand (definition classpath, dependency classpath) are
properly defined.
Documentation to the three methods has been added.
It mainly does three things:
* Clean up the implementation, removing unused values like
`globalPluginDefs`.
* Make the implementation more readable.
* And the big one: Remove the creation of a classloader that we were
instantiating but whose value we were throwing away. This has an impact
in performance, but I'm yet to benchmark how much it is.
This commit fixes most of the red squiggles created by the lack of
analysis of Contraband-generated Scala files. It does not end with all
the red squiggles but it substantially decreases the amount of them.
Previous commit used `synchronized` to ensure that the global reporter
was not reporting errors from other parsing sessions. Theoretically,
though, sbt could invoke parsing in parallel, so it's better to ensure
we remove the `synchronized` block, which could also be preventing some
JVM optimizations.
The following commit solves the issue by introducing a reporter id.
A reporter id is a unique identifier that is mapped to a reporter. Every
parsing session gets its own identifier, which then is reused for
recursive parsing. Error reports between recursive parses cannot collide
because the reporter is cleaned in `parse`.
The previous implementation was instantiating a toolbox to parse every
time it parsed a sbt file (and even recursively!!!).
This is inefficient and translates to instantiating a `ReflectGlobal`
every time we want to parse something.
This commit takes another approach:
1. It removes the dependency on `ReflectGlobal`.
2. It reuses the same `Global` and `Run` instances for parsing.
This is an efficient as it can get without doing a whole overhaul of it.
I think that in the future we may want to reimplement it to avoid the
recursive parsing to work around Scalac's bug.
This change was proposed by Jason in case that the new parsing mechanism
implemented later on has to be reverted. This change provides a good
baseline, but it's far from ideal with regard to readability of the
parser and performance.
The previous implementation was using the Scala runtime universe to
check whether a plugin had or not an `autoImport` member. This is a bad
idea for the following reasons:
* The first time you use it, you class load the whole Scalac compiler
universe. Not efficient. Measurements say this is about a second.
* There is a small overhead of going through the reflection API.
There exists a better approach that consists in checking if `autoImport`
exists with pure Java reflection. Since the class is already class
loaded, we check for:
* A class file named after the plugin FQN that includes `autoImport$` at
the end, which means that an object named `autoImport` exists.
* A field in the plugin class that is named `autoImport`.
This complies with the plugin sbt specification:
http://www.scala-sbt.org/1.0/docs/Plugins.html#Controlling+the+import+with+autoImport
We need to communicate the error states in the thread, so I added a `Future[Unit]` called `ready`.
If something goes wrong during the startup, like if the port is already taken, this can be used to communicate back to the main thread, and display the error accordingly.
The uglier but backward compatible fix for #3086 is to use u3 format with three slashes. This on Windows will resolve to `file:///C:/Users/foo/.sbt/preloaded`, and on Mac and Linux `file:////root/.sbt/preloaded/`. Mac and Linux are both tolerant of extra slashes on the front:
```
> eval new File(new URL("file:////Users/foo/.sbt/preloaded/").toURI)
[info] ans: java.io.File = /Users/foo/.sbt/preloaded
```
+ Don't notify ScriptMain users by moving the logic to xMain
+ Only trigger shell if shell is a defined command
+ Use existing Shell/BootCommand strings instead of new ones