Giter Site home page Giter Site logo

sbt-boilerplate's Introduction

sbt-boilerplate

Boilerplate is an sbt-plugin that generates stubs for code which has to be expanded for all numbers of arguments from 1 to 22. This is sometimes necessary to support all of the TupleX or FunctionX generically.

The plugin defines a simple template language for this purpose.

The template language

The template file contains mostly literal code with some control characters guiding the expansion. Expansion follows these rules:

  • The current number of arguments i is initialized to 22.
  • Code embraced in [# and #] is copied i times and the expansion is applied recursively with i being set accordingly.
    • It is possible to define a custom separator between the copied instances by putting the separator text between the # and the ] of the closing bracket. If no separator is supplied ", " is assumed.
    • You can specify a custom range i should iterate through by placing a term of the form <start>..<end> between the starting [ and # of an expansion. Either start or end can be omitted in which case the defaults are assumed.
  • Everywhere digit 1 is replaced by i, digit 0 is replaced by i - 1, and digit 2 is replaced by i + 1 unless the digit is prefixed with ##.
  • To encode the sharp '#' character precede it with a backslash e.g. "\#".

Examples

Apply function to tuple

Consider the task is to provide overloads for a function which can apply a function to a tuple for all numbers of arguments from 1 to 22.

Start by writing out the function for only one argument:

def applyFunc[P1, R](input: Tuple1[P1], func: (P1) => R): R =
  func(input._1)

For the function to be copied for each possible number of arguments, enclose it in [# and #] (the newline between the closing # and ] defines that instances should be separated by newline and not by the default ", "):

[#def applyFunc[P1, R](input: Tuple1[P1], func: (P1) => R): R =
  func(input._1)#
]

This will already expand to:

def applyFunc[P1, R](input: Tuple1[P1], func: (P1) => R): R =
  func(input._1)
def applyFunc[P2, R](input: Tuple2[P2], func: (P2) => R): R =
  func(input._2)
def applyFunc[P3, R](input: Tuple3[P3], func: (P3) => R): R =
  func(input._3)
def applyFunc[P4, R](input: Tuple4[P4], func: (P4) => R): R =
  func(input._4)
// ...

This is not yet what we want, because we P1 to expand to P1, P2, ..., Pi and input._1 to input._1, input._2, ..., input._i. So we embrace the parts to expand another time:

[#def applyFunc[[#P1#], R](input: Tuple1[[#P1#]], func: ([#P1#]) => R): R =
  func([#input._1#])#
]

This now expands correctly to

def applyFunc[P1, R](input: Tuple1[P1], func: (P1) => R): R =
  func(input._1)
def applyFunc[P1, P2, R](input: Tuple2[P1, P2], func: (P1, P2) => R): R =
  func(input._1, input._2)
def applyFunc[P1, P2, P3, R](input: Tuple3[P1, P2, P3], func: (P1, P2, P3) => R): R =
  func(input._1, input._2, input._3)
def applyFunc[P1, P2, P3, P4, R](input: Tuple4[P1, P2, P3, P4], func: (P1, P2, P3, P4) => R): R =
  func(input._1, input._2, input._3, input._4)

Usage

sbt-boilerplate currently supports sbt 1.x.

Put

addSbtPlugin("com.github.sbt" % "sbt-boilerplate" % "0.7.0")

into your plugins.sbt. sbt-boilerplate is an AutoPlugin which needs to be enabled using

enablePlugins(spray.boilerplate.BoilerplatePlugin)

The templates have to be put into the src/main/boilerplate directory and the file name must end with .template. The generated files will be put into the same hierarchy as they appear in src/main/boilerplate with the .template extension stripped off. If the stripped filename has no extension ".scala" is added automatically.

Known issues

  • Instances for zero arguments have to be supplied manually.

Projects using sbt-boilerplate

License

Copyright (c) 2012-2016 Johannes Rudolph

Published under the BSD 2-Clause License.

sbt-boilerplate's People

Contributors

dependabot[bot] avatar eed3si9n avatar jrudolph avatar ktoso avatar marklister avatar mkurz avatar nrinaudo avatar scala-steward avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sbt-boilerplate's Issues

Numbers in namespace templating

Hi guys,

Template

package org.parboiled2

object Test

in translated to

package org.parboiled23

object Test

How to keep namespace invariant to translation?

Updating to sbt 1.x, error: not found: value spray

I'm in the process of updating the sbt build for my project from 0.13.x to 1.x, and I'm at a loss while trying to get Boilerplate to be recognized by sbt. As per your instructions, I've added the following to my plugins.sbt and build.sbt

// plugins.sbt
addSbtPlugin("io.spray" % "sbt-boilerplate" % "0.6.1")
// build.sbt
lazy val core = (project in file("core"))
    .enablePlugins(spray.boilerplate.BoilerplatePlugin)
    ...
// build.properties
sbt.version = 1.2.3 // I also tried 1.0.0

I'm met with build.sbt:17: error: not found: value spray
I get similar errors if I try to import spray.boilerplate.BoilerplatePlugin or just .enablePlugins(BoilerplatePlugin)

I'm sure I'm missing something important, but haven't had any success with my searches.

Support 1-arity not being a Tuple1

I have some boilerplate to generate that revolves around case class apply/unapply. But the signature for unapply for a 1-arity product is Option[T], compare:

scala> case class CC1(x: Int); CC1.unapply _
defined class CC1
res0: CC1 => Option[Int] = $$Lambda$1308/693434027@58fbd02e

scala> case class CC2(x: Int, y: Int); CC2.unapply _
defined class CC2
res1: CC2 => Option[(Int, Int)] = $$Lambda$1313/233142783@7971c2a9

scala> case class CC3(x: Int, y: Int, z: Int); CC3.unapply _
defined class CC3
res2: CC3 => Option[(Int, Int, Int)] = $$Lambda$1314/1361241279@23e61112

Therefore I can't find a way to write a template that calls .1/.2/.. for 2+ arity, but skips it for 1-arity.

For the real world case, see eed3si9n/sjson-new#62.

Add a .scala extension to generates files

Generated files currently don't have an extension, which seems to confuse IntelliJ when it tries to locate sources. Is there a particular reason for the lack of extension, other than it's not strictly required by SBT?

Design discussion for JSR 223 enhancements.

I'm on holiday but some time soon I plan to start work on some JSR 223 enhancements to sbt-boilerplate. If necessary I'll maintain it as a separate fork.

Enhancement 1:

Parse the region between [ and # and evaluate it as a Scala Range. Use the expression to produce boilerplate.

Enhancement 2:

Create an environment containing global environment variables like maxArity

Enhancement 3:

Allow arbitrary Scala expressions in templates. Any -> String probably.

As a side effect the expression might alter the global environment like setting new maxArity etc.

@jrudolph: Any thoughts? Preferences? Is this a terrible idea?

Delete files generated from deleted templates?

This is rather a question: Should the plugin delete files generated from deleted templates? It currently overwrites files whose templates got updated.

Or is an explicit clean required here? How do other plugins behave in that regard?

Background: I often get compile errors after switching branches because of leftover generated files which became invalid. Is a clean recommended after switching branches in general?

Thanks!

Sharp escaping or using a character other than sharp

When generating a template with type-lambdas (like in ({ type Out[A] = ... })#Out), one runs into errors because of the sharp character in the type-lambda.

There seems to be no way of escaping it. As a quick fix for a unpublished yet project of mine, I made some changes in sbt-boilerplate so that users can use another character instead of #, by adding to their build.sbt a line of the form:

Boilerplate.boilerplateSpecialToken in Boilerplate.boilerplateGenerate := "$"

to use $ instead of # for example. These changes are in my fork (https://github.com/alexarchambault/sbt-boilerplate) for now.

So my question is: do you intend to allow escaping of the sharp character at some point? Or could my fix be of any interest to you?

Not all source directories searched

Using 0.6.0-SNAPSHOT

My project is a combined scala-js and scala-jvm project. Here is the build.sbt

The shared/src directory is not searched for templates.

It was a while ago but I think this hack fixed this problem.

[updated build.sbt link]

Release for sbt 1.0

AFAICS this was not done yet - we'll need this for Akka to be able to upgrade to 1.0.0

Parser parses and alters regions outside [#....#]

If I have a Template like this:

/** Thingy1 through 22 do blah blah blah */

[# Thingy1 #]

Then scaladoc part gets parsed as a LiteralString and then winds up getting mangled into
/** Thingy22 through 223 do blah blah blah */

Ideally we don't want any alteration of the template file except between [# and #]

This made a bit of a mess of my source; enough that a pull request to fix this is on its way...

Override max `i` for tests or non-production builds

Hello there, I have a project that utilizes boilerplate with a standard i of 15, but I don't always need 15, especially for tests. Having 15 slows down all builds. I would like to be able to override i for tests. Can this be done any way?

FixedString parser too primitive

If you are trying to prevent alteration of say "Tuple11" you need to rewrite it as "Tuple##1##1"

I'm adding REPL sessions to my scaladoc and this makes things quite messy. Pull request on the way.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.