Coder Social home page Coder Social logo

scala-abide's Introduction

Abide : Lint tooling for Scala

Abide aims to provide users with a simple framework for lint-like rule creation and verification. Abide rules are designed as small, self-contained units of logic which abstract concerns such as traversal and optimization away from the rule writter.

Using the tool

Abide is only available for sbt (and command line) for now, but will be ported to a Scala-IDE plugin and possibly to maven/gradle/etc as well. To add abide verification to an sbt project, three different options are available :

Important!

At this moment, abide has not been released. You need to run sbt publish-local in a local checkout of the abide repository.

Sbt Plugin

Activate the sbt-abide plugin in both scala 2.10 and 2.11 projects by extending your project/plugin.sbt file with

addSbtPlugin("com.typesafe" % "sbt-abide" % "0.1-SNAPSHOT")

abide requires Sbt version 0.13.5 or later. Make sure you have the following line in project/build.properties

sbt.version=0.13.5

Now you need to choose the rule libraries by adding the required jars to your dependencies in your project definitions (eg. build.sbt). Notice the abide configuration at the end of the line.

libraryDependencies += "com.typesafe" %% "abide-core" % "0.1-SNAPSHOT" % "abide"

One can also use sbt projects as rule libraries by using dependsOn(rules % "abide") in the project definition. This allows one to define project-specific rules!

This mode can run on scala 2.10 projects by using the compiler -Xsource:2.10 flag (automatically managed by the plugin), however one must force the use of the abide libraries version built against scala 2.11! You can do that by specifying the full cross-compiled name, instead of relying on the %% operator:

libraryDependencies += "com.typesafe" % "abide-core_2.11" % "0.1-SNAPSHOT" % "abide"

Compiler Plugin

Abide can be activated as a compiler plugin in scala 2.11 projects by extending the sbt build file with

libraryDependencies += compilerPlugin("com.typesafe" %% "abide" % "0.1-SNAPSHOT")
scalacOptions ++= Seq(
  "-P:abide:abidecp:<some.rules.classpath>",
  "-P:abide:ruleClass:<some.rule.Class>",
  "-P:abide:analyzerClass:<some.analyzer.generator.Module>",
  ...)

or simply add these options to your call to scalac to enable abide during your standard compilation run.

Since sbt configurations are not available to compiler plugins, the abidecp argument is required to specify the classpath where the abide rules are located. In turn, the actual paths to these rules are specified through the ruleClass argument (which will typically appear multiple times, once per rule) and plugin analyzer generators will appear in analyzerClass arguments (also multiple instances).

While slightly more complexe than the following alternative, this mode provides integration capabilities for non-sbt build tools like eclipse or maven.

Command line

The abide compiler plugin can also be used directly on the command line by adding the plugin to your scalac command and using the options described in the compiler plugin as cli arguments:

scalac -Xplugin:<path/to/abide.jar>                            \
       -P:abide:abidecp:<some.rules.classpath>                 \
       -P:abide:ruleClass:<some.rule.Class>                    \
       -P:abide:analyzerClass:<some.analyzer.generator.Module> \
       ...

Note that this feature, as in the compiler plugin case, can only be used on scala 2.11 projects.

Existing plugins

The abide framework comes with a few pre-made rule packages that can be selectively enabled as discussed in the previous section. The list of available packages along with the associated ivy dependency are:

  1. rules/core provided by "com.typesafe" %% "abide-core" % "0.1-SNAPSHOT"

  2. rules/extra provided by "com.typesafe" %% "abide-extra" % "0.1-SNAPSHOT"

  3. rules/akka provided by "com.typesafe" %% "abide-akka" % "0.1-SNAPSHOT"

Extending Abide

Setting aside bugfixes and basic feature modification, abide components are generally loosely coupled and self-contained to enable simple extensions to the framework. Such extensions will typically fall into one of three different categories and will vary in complexity. From simplest (and most useful extension point) to most involved:

  1. rule extension
    The abide framework initially ships with few rules but provides a powerful extension point to accomodate user-defined rule verification. These rules can either be defined locally (using the Project(...).dependsOn(rules % "abide") construction) or shared over github by submitting new rules as pull requests to this repository.

  2. directive extension
    Abide rules all share a minimal amount of context, namely the universe instance which defines the compiler AST cake. This context is passed to rules through the val context : Context constructor parameter that each rule must define. Directives will typically be mixed in to the shared context object and cache computation results when these can be shared between rules.

  3. analyzer extension
    When rule application can benefit from some global traversal logic, or partial tree analysis, these computations are performed in an Analyzer subtype. These analyzers are typically non-trivial and will be integrated into the main abide deliverable to then be shared by all rules. However, analyzers can also be provided alongside rules in plugin libraries.

The provided extension mechanism uses a plugin architecture based on an xml description that specifies plugin capabilities. This description sits at the base of the resources directory, in abide-plugin.xml and has the following structure:

<plugin>
  <rule class="some.rule.Class" />
  <rule class="some.other.rule.Class" />
  <analyzer class="some.analyzer.generator.Class" />
</plugin>

Directives don't need to (and shouldn't) be specified in the plugin description as they will be statically referenced in the source code (and they can't be dynamically subsumed like analyzers).

Further Work

  • The abide compiler plugin needs to manage rule enabling and disabling. This should be implemented in scala.tools.abide.compiler.AbidePlugin in the component.apply method by replacing the analyzer filter (first argument of scala gen(_ => true)(unit.body)) by an actual filter.

  • Extending build tool support. Abide plugins for eclipse, gradle, maven, etc would be a nice feature extension to the framework. Such extensions should be relatively easy to implement by using the compiler plugin and manually injecting -P:abide:... command line arguments to configure the framework. Abide could also be run on the result of a presentation compiler run, and scala.tools.abide.compiler.AbidePlugin would be a good place to start for loading rules, contexts, generators, etc. One can also look at the tests to witness abide verification in action without the compiler plugin.

  • Adding new Presenter types. For now, abide can only output warnigns as compiler warnings, but it would be nice, for example, to be able to output interactive HTML5 reports.

  • Enabling cross-unit rules by writing a new analyzer. The base would resemble that of the FusingTraversalAnalyzer but would additionnaly require keeping track of the result of previous traversals for incremental compilation integration.

scala-abide's People

Contributors

adriaanm avatar andrewconner avatar dragos avatar lewix avatar samarion avatar

Watchers

 avatar  avatar  avatar

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.