All Projects → sangria-graphql → macro-visit

sangria-graphql / macro-visit

Licence: Apache-2.0 license
A macro-based generic visitor generator

Programming Languages

scala
5932 projects

Projects that are alternatives of or similar to macro-visit

pascal-interpreter
A simple interpreter for a large subset of Pascal language written for educational purposes
Stars: ✭ 21 (-8.7%)
Mutual labels:  ast, visitor
clickhouse-ast-parser
AST parser and visitor for ClickHouse SQL
Stars: ✭ 60 (+160.87%)
Mutual labels:  ast, visitor
Unified
☔️ interface for parsing, inspecting, transforming, and serializing content through syntax trees
Stars: ✭ 3,036 (+13100%)
Mutual labels:  ast
rehype-dom
HTML processor to parse and compile with browser APIs, powered by plugins
Stars: ✭ 20 (-13.04%)
Mutual labels:  ast
astexplorer-go
No description or website provided.
Stars: ✭ 17 (-26.09%)
Mutual labels:  ast
Gulp Strip Debug
Strip console, alert, and debugger statements from JavaScript code
Stars: ✭ 242 (+952.17%)
Mutual labels:  ast
java-ast
Java Parser for JavaScript/TypeScript (based on antlr4ts)
Stars: ✭ 58 (+152.17%)
Mutual labels:  ast
Php Parser
A PHP parser written in PHP
Stars: ✭ 15,101 (+65556.52%)
Mutual labels:  ast
deco
Minimalist Function Decorators for Elixir
Stars: ✭ 21 (-8.7%)
Mutual labels:  ast
html5parser
A super tiny and fast html5 AST parser.
Stars: ✭ 153 (+565.22%)
Mutual labels:  ast
gox
JSX for Go
Stars: ✭ 165 (+617.39%)
Mutual labels:  ast
stutter
Implement a Lisp, in C, from scratch, no libs
Stars: ✭ 65 (+182.61%)
Mutual labels:  ast
Esdoc
ESDoc - Good Documentation for JavaScript
Stars: ✭ 2,706 (+11665.22%)
Mutual labels:  ast
awesome-ruby-ast
A list of awesome tools and libraries which deals with ASTs in Ruby
Stars: ✭ 24 (+4.35%)
Mutual labels:  ast
Tsutils
utility functions for working with typescript's AST
Stars: ✭ 240 (+943.48%)
Mutual labels:  ast
parser-reflection
Parser Reflection API - Provides source code analysis without loading classes into the PHP memory
Stars: ✭ 97 (+321.74%)
Mutual labels:  ast
Cppast.net
CppAst is a .NET library providing a C/C++ parser for header files powered by Clang/libclang with access to the full AST, comments and macros
Stars: ✭ 228 (+891.3%)
Mutual labels:  ast
php2python
Convert PHP code to Python under CGI (beta)
Stars: ✭ 44 (+91.3%)
Mutual labels:  ast
sast
Parse CSS, Sass, SCSS, and Less into a unist syntax tree
Stars: ✭ 51 (+121.74%)
Mutual labels:  ast
TypeScriptAST
.NET port of Microsoft's TypeScript parser for simple AST manipulation
Stars: ✭ 37 (+60.87%)
Mutual labels:  ast

Macro Visit

A macro-based generic visitor generator

Continuous Integration Maven Central License Join the chat at https://gitter.im/sangria-graphql/sangria

SBT Configuration:

libraryDependencies += "org.sangria-graphql" %% "macro-visit" % "<latest version>"

Introduction

Writing visitor code can be quite tedious, especially if some nodes need to be transformed (in immutable way) along the way. This becomes even harder if performance is a concern and data structures are deeply recursive, so non tail-recursive approach is not an option. macro-visit provides very simple way to create type-safe visitor code for arbitrary sealed case class hierarchies. Generated visitor provides following features:

  • Non-recursive traversal, which means all state is managed in the heap and you will not run into stack overflow errors with deep recursive data structures.
  • Optimised for performance and memory footprint. Generated code for class hierarchy traversal is compiled into tight while loop.
  • Allows to transform traversed object in immutable way. It generates code that uses case class's copy method to get updated instance of object in most efficient way (if object has several changes, it would be copied only once)
  • Allows to break traversal at any given node and skip nodes
  • Supports List, Vector, Seq and Option traversal

Generated visitors can be very useful for traversing and transforming AST (Abstract Syntax Tree).

Assuming that the base type is called Ast, following visitors are supported:

  • Visit(enter, leave), where enter and leave are Ast => VisitorCommand functions - it recursively visits all instances of Ast type
  • VisitAnyField(fn) - it visits all fields with special type S (which is different from Ast) along the way
  • VisitAnyFieldByName(fieldName, fn) - it visits all fields with provided name and special type S (which is different from Ast) along the way

Following visitor commands are supported:

  • Skip
  • Continue
  • Break
  • Transform(newValue, controlCommand)
  • Delete
  • DeleteAndBreak

Example

Here is how basic usage looks like:

import sangria.visitor._

val res = visit[Ast](root,
  Visit[Field](f => if (f.name == "hex") VisitorCommand.Delete else VisitorCommand.Continue),
  Visit[IntValue](v => VisitorCommand.Transform(IntValue(v.value + 1))))

Macro will look for all subtypes of Ast and then will generate traversal code for it with provided visitors. Visit takes 2 functions as an argument enter and leave which both have Ast ⇒ VisitorCommand type.

Given following AST definitions:

sealed trait Ast

case class Vertex(name: String, edges: List[Edge], fields: Vector[Field] = Vector.empty) extends Ast
case class Edge(weight: Int, toVertex: Vertex) extends Ast
case class Field(name: String, value: Option[Value]) extends Ast

sealed trait Value extends Ast

case class StringValue(value: String) extends Value
case class IntValue(value: Int) extends Value

and sample data:

val root =
  Vertex("start", List(
    Edge(1, Vertex("colors", List(
      Edge(2, Vertex("RED", Nil, Vector(
        Field("intensity", Some(IntValue(123))),
        Field("hex", Some(StringValue("#FF0000")))
      ))),
      Edge(100, Vertex("GREEN", Nil, Vector(
        Field("hex", Some(StringValue("#00FF00")))
      )))
    ))),
    Edge(42, Vertex("books", List(
      Edge(1, Vertex("The Hobbit", Nil, Vector(
        Field("pages", Some(IntValue(320)))
      )))
    )))
  ))

The result of the transformation will look like this:

Vertex("start", List(
  Edge(1, Vertex("colors", List(
    Edge(2,Vertex("RED", Nil, Vector(
      Field("intensity", Some(IntValue(124)))))),
    Edge(100, Vertex("GREEN", Nil, Vector.empty))), Vector.empty)),
  Edge(42, Vertex("books", List(
    Edge(1, Vertex("The Hobbit", Nil, Vector(
      Field("pages", Some(IntValue(321))))))),
    Vector.empty))),
  Vector.empty)

License

macro-visit is licensed under Apache License, Version 2.0.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].