aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorChristopher Vogt <oss.nsp@cvogt.org>2017-03-20 22:09:38 -0400
committerChristopher Vogt <oss.nsp@cvogt.org>2017-03-27 19:56:13 -0400
commitbba2abe7ee38b8903822a07578c46466923d13ed (patch)
treea357fb8def6f58a9ea9a37411f3f5640dcb525fe /doc
parentd2f8cade709b7d55a93e18592b6e38247d648ca9 (diff)
downloadcbt-bba2abe7ee38b8903822a07578c46466923d13ed.tar.gz
cbt-bba2abe7ee38b8903822a07578c46466923d13ed.tar.bz2
cbt-bba2abe7ee38b8903822a07578c46466923d13ed.zip
start modularizing cbt into libraries
this extracts certain parts of cbt into stand-alone libraries, which can be published to maven and used outside of cbt. This also adds scalariform for these parts of the code. This slows down cbt’s own build a lot because of the number of projects involved! So we’ll follow this by a bunch of performance tweak commits.
Diffstat (limited to 'doc')
-rw-r--r--doc/design.md35
1 files changed, 35 insertions, 0 deletions
diff --git a/doc/design.md b/doc/design.md
index 28bbdaa..38e5434 100644
--- a/doc/design.md
+++ b/doc/design.md
@@ -83,6 +83,40 @@ class Build(val context: Context) extends SomePlugin{
Such a simple replacement of `b` while keeping all other arguments would
not be easily possible if doSomething was a def not a case class.
+## Why do the libraries have ops packages and Module traits?
+
+Java's and Scala's package system does allow importing things,
+but not exporting things. Everything has to be imported
+explicitly anywhere it is supposed to be used. It's just a
+package system, not a module system. This leads to a lot of
+import boiler plate. CBT tries to minimize the imports
+necessary for it's use however. So how to we do this while
+at the same time allowing modularization? In particular, how
+do we do this with stand-alone methods and implicit classes
+that have to be in an object, e.g. the package object?
+
+Scala's traits can be used as a module system that supports exports.
+This means we can take several modules (traits) and merge them into
+something that exports everything defined in any of them. Basically
+inheriting a trait means importing names into the scope of the
+inheriting class and exporting those names to the class's users.
+
+CBT's libraries define Module traits, which their package objects inherit.
+This makes it easy to use the libraries by itself. CBT's core however
+also inherits all of the library Module traits in it's package object,
+meaning that by a simple `import cbt._` you get everything from all
+libraries. This solves the import boiler plate.
+
+For implicit classes it is a little bit trickier as those should
+extend AnyVal for performance reasons, but that's only allowed in
+an object, not a trait. So what we do instead is put Universal traits
+(see http://docs.scala-lang.org/overviews/core/value-classes.html)
+containing all the logic into a helper package `ops`. The package
+objects that want to offer the implicit classes now define them
+extending the Universal traits. This means a little boiler plate
+where the package object is define, but also solves the import
+boiler plate everywhere else.
+
## What is newBuild and why do we need it?
Methods in a class can call each other and thereby effectively form a graph.
@@ -137,3 +171,4 @@ trait CrossVersionPlugin{
Problem solved. In fact this allows for a very, very flexible way of
creating differents variants of your build.
+