From bba2abe7ee38b8903822a07578c46466923d13ed Mon Sep 17 00:00:00 2001 From: Christopher Vogt Date: Mon, 20 Mar 2017 22:09:38 -0400 Subject: 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. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- doc/design.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'doc') 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. + -- cgit v1.2.3