{"id":23813593,"url":"https://github.com/dmytromitin/auxify","last_synced_at":"2025-09-06T22:30:48.008Z","repository":{"id":57719720,"uuid":"139704569","full_name":"DmytroMitin/AUXify","owner":"DmytroMitin","description":"Introduces macro/meta annotations @ aux, @ self, @ instance, @ apply, @ delegated, @ syntax and String-based type class LabelledGeneric","archived":false,"fork":false,"pushed_at":"2020-07-04T09:44:29.000Z","size":14525,"stargazers_count":29,"open_issues_count":23,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-07T11:36:56.541Z","etag":null,"topics":["code-generation","dependent-types","extension-methods","macros","metaprogramming","scala","scalafix","scalameta","semanticdb","shapeless","simulacrum","typeclass","typeclasses","typelevel-programming"],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DmytroMitin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-07-04T10:06:06.000Z","updated_at":"2025-02-11T20:36:13.000Z","dependencies_parsed_at":"2022-09-26T21:40:54.712Z","dependency_job_id":null,"html_url":"https://github.com/DmytroMitin/AUXify","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/DmytroMitin/AUXify","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DmytroMitin%2FAUXify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DmytroMitin%2FAUXify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DmytroMitin%2FAUXify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DmytroMitin%2FAUXify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DmytroMitin","download_url":"https://codeload.github.com/DmytroMitin/AUXify/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DmytroMitin%2FAUXify/sbom","scorecard":{"id":41349,"data":{"date":"2025-08-11","repo":{"name":"github.com/DmytroMitin/AUXify","commit":"fe7bb2a857f8c6440e83c2c0c4ffd5c43541d00e"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-14T21:39:21.135Z","repository_id":57719720,"created_at":"2025-08-14T21:39:21.135Z","updated_at":"2025-08-14T21:39:21.135Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273973354,"owners_count":25200575,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-06T02:00:13.247Z","response_time":2576,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code-generation","dependent-types","extension-methods","macros","metaprogramming","scala","scalafix","scalameta","semanticdb","shapeless","simulacrum","typeclass","typeclasses","typelevel-programming"],"created_at":"2025-01-02T03:19:40.562Z","updated_at":"2025-09-06T22:30:47.683Z","avatar_url":"https://github.com/DmytroMitin.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AUXify\n\n[![Build Status](https://travis-ci.org/DmytroMitin/AUXify.svg?branch=master)](https://travis-ci.org/DmytroMitin/AUXify)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.dmytromitin/auxify-macros_2.13/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.dmytromitin/auxify-macros_2.13)\n[![Maven Central](https://img.shields.io/maven-central/v/com.github.dmytromitin/auxify-macros_2.13.svg?label=maven%20central\u0026color=success)](https://search.maven.org/search?q=g:%22com.github.dmytromitin%22%20AND%20a:%22auxify-macros_2.13%22)\n[![Sonatype Snapshots](https://img.shields.io/nexus/r/https/oss.sonatype.org/com.github.dmytromitin/auxify-macros_2.13.svg?color=success)](https://oss.sonatype.org/content/groups/public/com/github/dmytromitin/auxify-macros_2.13/)\n[![javadoc](https://javadoc.io/badge2/com.github.dmytromitin/auxify-macros_2.13/javadoc.svg)](https://javadoc.io/doc/com.github.dmytromitin/auxify-macros_2.13)\n[![Scaladex](https://index.scala-lang.org/dmytromitin/auxify/auxify-macros/latest.svg?color=success)](https://index.scala-lang.org/dmytromitin/auxify/auxify-macros)\n[![Join the chat at https://gitter.im/DmytroMitin/AUXify](https://badges.gitter.im/DmytroMitin/AUXify.svg)](https://gitter.im/DmytroMitin/AUXify?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\n[mvnrepository](https://mvnrepository.com/artifact/com.github.dmytromitin)\n[repo1.maven](https://repo1.maven.org/maven2/com/github/dmytromitin/)\n\n## Contents\n- [Using AUXify-Shapeless](#using-auxify-shapeless)\n- [Using AUXify-Macros](#using-auxify-macros)\n  * [@aux (helper for type refinement)](#aux-helper-for-type-refinement)\n  * [@self](#self)\n  * [@instance (constructor)](#instance--constructor-)\n  * [@apply (materializer)](#apply--materializer-)\n  * [@delegated](#delegated)\n  * [@syntax](#syntax)\n  * [@poly](#poly)\n- [Using AUXify-Meta](#using-auxify-meta)\n  * [Code generation with Scalafix](#code-generation-with-scalafix)\n  * [Rewriting with Scalafix](#rewriting-with-scalafix)\n  * [Code generation with Scalameta](#code-generation-with-scalameta)\n\n## Using AUXify-Shapeless\nWrite in `build.sbt`\n```scala\nscalaVersion := \"2.13.3\"\n//scalaVersion := \"2.12.11\"\n//scalaVersion := \"2.11.12\"\n//scalaVersion := \"2.10.7\"\n\nresolvers += Resolver.sonatypeRepo(\"public\")\n\nlibraryDependencies ++= Seq(\n  \"com.github.dmytromitin\" %% \"auxify-shapeless\" % [LATEST VERSION],\n  \"com.github.dmytromitin\" %% \"shapeless\" % (CrossVersion.partialVersion(scalaVersion.value) match {\n    case Some((2, v)) if v \u003e= 11 =\u003e \"2.4.0-M1-30032020-e6c3f71-PATCH\"\n    case _                       =\u003e \"2.4.0-SNAPSHOT-18022020-bf55524-PATCH\"\n  })\n)\n```\n\nHelps to overcome [Shapeless](https://github.com/milessabin/shapeless/) limitation that [`shapeless.LabelledGeneric`](https://github.com/milessabin/shapeless/wiki/Feature-overview:-shapeless-2.0.0#generic-representation-of-sealed-families-of-case-classes) is `Symbol`-based rather than `String`-based.\n\nIntroduces type classes `SymbolToString`, `StringToSymbol` to convert between symbol singleton type and string singleton type\n```scala\nimplicitly[StringToSymbol.Aux[\"a\", Symbol @@ \"a\"]]\nimplicitly[SymbolToString.Aux[Symbol @@ \"a\", \"a\"]]\nstringToSymbol(\"a\") // returns Symbol(\"a\") of type Symbol @@ \"a\"\nsymbolToString(Symbol(\"a\")) // returns \"a\" of type \"a\"\n```\nand `String`-based type class `com.github.dmytromitin.auxify.shapeless.LabelledGeneric`\n```scala\ncase class A(i: Int, s: String, b: Boolean)\nimplicitly[LabelledGeneric.Aux[A, Record.`\"i\" -\u003e Int, \"s\" -\u003e String, \"b\" -\u003e Boolean`.T]]\nLabelledGeneric[A].to(A(1, \"a\", true)) // field[\"i\"](1) :: field[\"s\"](\"a\") :: field[\"b\"](true) :: HNil\nLabelledGeneric[A].from(field[\"i\"](1) :: field[\"s\"](\"a\") :: field[\"b\"](true) :: HNil) // A(1, \"a\", true)\n```\nAlso there are convenient syntaxes\n```scala\nimport com.github.dmytromitin.auxify.shapeless.hlist._\nimport StringsToSymbols.syntax._\n(\"a\".narrow :: \"b\".narrow :: \"c\".narrow :: HNil).stringsToSymbols // 'a.narrow :: 'b.narrow :: 'c.narrow :: HNil\nimport SymbolsToStrings.syntax._\n('a.narrow :: 'b.narrow :: 'c.narrow :: HNil).symbolsToStrings // \"a\".narrow :: \"b\".narrow :: \"c\".narrow :: HNil\n\nimport com.github.dmytromitin.auxify.shapeless.coproduct._\nimport StringsToSymbols.syntax._\n(Inr(Inr(Inl(\"c\".narrow))) : \"a\" :+: \"b\" :+: \"c\" :+: CNil).stringsToSymbols // Inr(Inr(Inl('c.narrow))) : (Symbol @@ \"a\") :+: (Symbol @@ \"b\") :+: (Symbol @@ \"c\") :+: CNil\nimport SymbolsToStrings.syntax._\n(Inr(Inr(Inl('c.narrow))) : (Symbol @@ \"a\") :+: (Symbol @@ \"b\") :+: (Symbol @@ \"c\") :+: CNil).symbolsToStrings // Inr(Inr(Inl(\"c\".narrow))) : \"a\" :+: \"b\" :+: \"c\" :+: CNil\n\nimport com.github.dmytromitin.auxify.shapeless.record._\nimport StringsToSymbols.syntax._\n(field[\"a\"](1) :: field[\"b\"](\"s\") :: field[\"c\"](true) :: HNil).stringsToSymbols // field[Symbol @@ \"a\"](1) :: field[Symbol @@ \"b\"](\"s\") :: field[Symbol @@ \"c\"](true) :: HNil\nimport SymbolsToStrings.syntax._\n(field[Symbol @@ \"a\"](1) :: field[Symbol @@ \"b\"](\"s\") :: field[Symbol @@ \"c\"](true) :: HNil).symbolsToStrings // field[\"a\"](1) :: field[\"b\"](\"s\") :: field[\"c\"](true) :: HNil\n\nimport com.github.dmytromitin.auxify.shapeless.union._\nimport StringsToSymbols.syntax._\n(Inr(Inr(Inl(field[\"c\"](true)))): Union.`\"a\" -\u003e Int, \"b\" -\u003e String, \"c\" -\u003e Boolean`.T).stringsToSymbols // Inr(Inr(Inl(field[Witness.`'c`.T](true)))): Union.`'a -\u003e Int, 'b -\u003e String, 'c -\u003e Boolean`.T\nimport SymbolsToStrings.syntax._\n(Inr(Inr(Inl(field[Symbol @@ \"c\"](true)))): Union.`'a -\u003e Int, 'b -\u003e String, 'c -\u003e Boolean`.T).symbolsToStrings // Inr(Inr(Inl(field[Witness.`\"c\"`.T](true)))): Union.`\"a\" -\u003e Int, \"b\" -\u003e String, \"c\" -\u003e Boolean`.T\n```\n\nYou can play with AUXify online at Scastie: https://scastie.scala-lang.org/r52fCgloRc2VVM5FnNmbsQ\n\n## Using AUXify-Macros\nWrite in `build.sbt`\n```scala\nscalaVersion := \"2.13.3\"\n//scalaVersion := \"2.12.11\"\n//scalaVersion := \"2.11.12\"\n//scalaVersion := \"2.10.7\"\n\nresolvers += Resolver.sonatypeRepo(\"public\")\n\nlibraryDependencies += \"com.github.dmytromitin\" %% \"auxify-macros\" % [LATEST VERSION]\n\nscalacOptions += \"-Ymacro-annotations\" // in Scala \u003e= 2.13\n//addCompilerPlugin(\"org.scalamacros\" % \"paradise\" % \"2.1.1\" cross CrossVersion.full) // in Scala \u003c= 2.12\n```\n\n## @aux (helper for type refinement)\nTransforms\n```scala\n@aux\ntrait Add[N \u003c: Nat, M \u003c: Nat] {\n  type Out \u003c: Nat\n  def apply(n: N, m: M): Out\n}\n```\ninto\n```scala\ntrait Add[N \u003c: Nat, M \u003c: Nat] {\n  type Out \u003c: Nat\n  def apply(n: N, m: M): Out\n}\n\nobject Add {\n  type Aux[N \u003c: Nat, M \u003c: Nat, Out0 \u003c: Nat] = Add[N, M] { type Out = Out0 }\n}\n```\nSo it can be used:\n```scala\nimplicitly[Add.Aux[_2, _3, _5]]\n```\nConvenient for type-level programming.\n\n## @self\nTransforms\n```scala\n@self\nsealed trait Nat {\n  type ++ = Succ[Self]\n}\n\n@self\ncase object _0 extends Nat \n\ntype _0 = _0.type\n\n@self\ncase class Succ[N \u003c: Nat](n: N) extends Nat\n```\ninto\n```scala\nsealed trait Nat { self =\u003e\n  type Self \u003e: self.type \u003c: Nat { type Self = self.Self }\n  type ++ = Succ[Self]\n}\n\ncase object _0 extends Nat {\n  override type Self = _0\n}\n\ntype _0 = _0.type\n\ncase class Succ[N \u003c: Nat](n: N) extends Nat {\n  override type Self = Succ[N]\n}\n```\nConvenient for type-level programming.\n\nGenerating lower bound `\u003e: self.type` and/or F-bound `type Self = self.Self` for trait can be switched off\n```scala\n@self(lowerBound = false, fBound = false)\n```\n\n## @instance (constructor)\nTransforms\n```scala\n@instance\ntrait Monoid[A] {\n  def empty: A\n  def combine(a: A, a1: A): A\n}\n```\ninto\n```scala\ntrait Monoid[A] {\n  def empty: A\n  def combine(a: A, a1: A): A\n}\n\nobject Monoid {\n  def instance[A](f: =\u003e A, f1: (A, A) =\u003e A): Monoid[A] = new Monoid[A] {\n    override def empty: A = f\n    override def combine(a: A, a1: A): A = f1(a, a1)\n  }\n}\n```\nSo it can be used\n```scala\nimplicit val intMonoid: Monoid[Int] = instance(0, _ + _)\n```\n\nPolymorphic methods are not supported (since Scala 2 lacks polymorphic functions).\n\n## @apply (materializer)\nTransforms\n```scala\n@apply\ntrait Show[A] {\n  def show(a: A): String\n}\n```\ninto \n```scala\ntrait Show[A] {\n  def show(a: A): String\n}\n\nobject Show {\n  def apply[A](implicit inst: Show[A]): Show[A] = inst\n}\n```\nSo it can be used\n```scala\nShow[Int].show(10)\n```\n\nMethod materializing type class can return more precise type than the one of implicit to be found (like `the` in [Shapeless](https://github.com/milessabin/shapeless) or `summon` in [Dotty](https://github.com/lampepfl/dotty)).\nFor example\n```scala\n@apply\ntrait Add[N \u003c: Nat, M \u003c: Nat] {\n  type Out \u003c: Nat\n  def apply(n: N, m: M): Out\n}\n```\nis transformed into\n```scala\ntrait Add[N \u003c: Nat, M \u003c: Nat] {\n  type Out \u003c: Nat\n  def apply(n: N, m: M): Out\n}\n\nobject Add {\n  def apply[N \u003c: Nat, M \u003c: Nat](implicit inst: Add[N, M]): Add[N, M] { type Out = inst.Out } = inst\n}\n```\n[Simulacrum](https://github.com/typelevel/simulacrum) annotation `@typeclass` also generates, among other, materializer but doesn't support type classes with multiple type parameters.\n\n## @delegated\nGenerates methods in companion object delegating to implicit instance of trait (type class).\n\nTransforms\n```scala\n@delegated\ntrait Show[A] {\n  def show(a: A): String\n}\n```\ninto\n```scala\ntrait Show[A] {\n  def show(a: A): String\n}\n\nobject Show {\n  def show[A](a: A)(implicit inst: Show[A]): String = inst.show(a)\n}\n```\nSo it can be used\n`````scala\nShow.show(10)\n`````\n\n## @syntax\nTransforms\n```scala\n@syntax\ntrait Monoid[A] {\n  def empty: A\n  def combine(a: A, a1: A): A\n}\n\n```\ninto\n```scala\ntrait Monoid[A] {\n  def empty: A\n  def combine(a: A, a1: A): A\n}\n\nobject Monoid {\n  object syntax {\n    implicit class Ops[A](a: A) {\n      def combine(a1: A)(implicit inst: Monoid[A]): A = inst.combine(a, a1)\n    }\n  }\n}\n```\nSo it can be used\n```scala\nimport Monoid.syntax._\n2 combine 3\n```\n[Simulacrum](https://github.com/typelevel/simulacrum) annotation `@typeclass` also generates syntax but doesn't support type classes with multiple type parameters.\n\nInheritance of type classes is not supported (anyway it's [broken](https://typelevel.org/blog/2016/09/30/subtype-typeclasses.html)).\n\n## @poly\nTransforms\n```scala\n@poly\ntrait Add[N \u003c: Nat, M \u003c: Nat] {\n  type Out \u003c: Nat\n  def apply(n: N, m: M): Out\n}\n\n```\ninto\n```scala\ntrait Add[N \u003c: Nat, M \u003c: Nat] {\n  type Out \u003c: Nat\n  def apply(n: N, m: M): Out\n}\n\nobject Add {\n  object addPoly extends Poly2 {\n    implicit def cse[N \u003c: Nat, M \u003c: Nat](implicit add: Add[N, M]): Case.Aux[N, M, add.Out] = at((n, m) =\u003e add(n, m)) \n  }\n}\n```\n\n`@poly` is not implemented yet. See [issue](https://github.com/DmytroMitin/AUXify/issues/34).\n\n## Using AUXify-Meta\n\nCurrently only `@aux` is implemented as Scalafix rewriting rule. It's a semantic rule since we need companion object.\n\nMeta annotation `@aux` works only with classes on contrary to macro annotation `@aux` working only with traits. \n[This will be fixed.](https://github.com/DmytroMitin/AUXify/issues/10) \n\n### Code generation with Scalafix\nFor code generation with [Scalameta](https://scalameta.org/) + [SemanticDB](https://scalameta.org/docs/semanticdb/guide.html) + [Scalafix](https://scalacenter.github.io/scalafix/) write in `project/plugins.sbt`\n```scala\naddSbtPlugin(\"ch.epfl.scala\" % \"sbt-scalafix\" % \"0.9.18\")\n```\nand in `build.sbt`\n```scala\nimport com.geirsson.coursiersmall.{Repository =\u003e R}\n\nlazy val V = _root_.scalafix.sbt.BuildInfo\n\ninThisBuild(Seq(\n  scalaVersion := V.scala213,\n  addCompilerPlugin(scalafixSemanticdb),\n  scalafixResolvers in ThisBuild += new R.Maven(\"https://oss.sonatype.org/content/groups/public/\"),\n  // brings rewriting rules\n  scalafixDependencies in ThisBuild += \"com.github.dmytromitin\" %% \"auxify-meta\" % [LATEST VERSION],\n  scalacOptions += \"-Yrangepos\" // for SemanticDB\n))\n\nlazy val in = project\n  .settings(\n    // brings meta annotations\n    libraryDependencies += \"com.github.dmytromitin\" %% \"auxify-meta-core\" % [LATEST VERSION]\n  )\n\nlazy val out = project\n  .settings(\n    sourceGenerators.in(Compile) += Def.taskDyn {\n      val root = baseDirectory.in(ThisBuild).value.toURI.toString\n      val from = sourceDirectory.in(in, Compile).value\n      val to = sourceManaged.in(Compile).value\n      val outFrom = from.toURI.toString.stripSuffix(\"/\").stripPrefix(root)\n      val outTo = to.toURI.toString.stripSuffix(\"/\").stripPrefix(root)\n      Def.task {\n        scalafix\n          .in(in, Compile)\n          .toTask(s\" AuxRule --out-from=$outFrom --out-to=$outTo\")\n          .value\n        (to ** \"*.scala\").get\n      }\n    }.taskValue,\n    \n    // for import statement and if meta annotation is not expanded\n    libraryDependencies += \"com.github.dmytromitin\" %% \"auxify-meta-core\" % [LATEST VERSION]\n  )\n```\nAnnotated code should be placed in `in/src/main/scala`. Code generation in `out/target/scala-2.13/src_managed/main/scala` can be run with `sbt out/compile`.\n\nExample project is [here](https://github.com/DmytroMitin/scalafix-codegen).\n\n### Rewriting with Scalafix\nFor using rewriting rules with [Scalameta](https://scalameta.org/) + [SemanticDB](https://scalameta.org/docs/semanticdb/guide.html) + [Scalafix](https://scalacenter.github.io/scalafix/) write in `project/plugins.sbt`\n```scala\naddSbtPlugin(\"ch.epfl.scala\" % \"sbt-scalafix\" % \"0.9.18\")\n```\nand in `build.sbt`\n```scala\n// on the top\nimport com.geirsson.coursiersmall.{Repository =\u003e R}\nscalafixResolvers in ThisBuild += new R.Maven(\"https://oss.sonatype.org/content/groups/public/\")\nscalafixDependencies in ThisBuild += \"com.github.dmytromitin\" %% \"auxify-meta\" % [LATEST VERSION]\n\nscalaVersion := \"2.13.3\"\n//scalaVersion := \"2.12.11\"\n//scalaVersion := \"2.11.12\"\n\nlibraryDependencies += \"com.github.dmytromitin\" %% \"auxify-meta-core\" % [LATEST VERSION]\n\naddCompilerPlugin(scalafixSemanticdb)\n\nscalacOptions += \"-Yrangepos\" // for SemanticDB\n```\n\nRewriting can be run with `sbt \"scalafix AuxRule\"` (details are [here](https://scalacenter.github.io/scalafix/docs/users/installation.html)).\n\n### Code generation with Scalameta\nFor code generating syntacticly with pure [Scalameta](https://scalameta.org/) (without [SemanticDB](https://scalameta.org/docs/semanticdb/guide.html) and [Scalafix](https://scalacenter.github.io/scalafix/)) write in `project/build.sbt`\n```scala\nresolvers += Resolver.sonatypeRepo(\"public\")\nlibraryDependencies += \"com.github.dmytromitin\" %% \"auxify-syntactic-meta\" % [LATEST VERSION]\n```\nand in `build.sbt`\n```scala\ninThisBuild(Seq(\n  scalaVersion := \"2.13.3\"\n  //scalaVersion := \"2.12.11\"\n  //scalaVersion := \"2.11.12\"\n))\n\nlazy val in = project\n  .settings(\n    libraryDependencies += \"com.github.dmytromitin\" %% \"auxify-meta-core\" % [LATEST VERSION]\n  )\n\nlazy val out = project\n  .settings(\n    sourceGenerators in Compile += Def.task {\n      import com.github.dmytromitin.auxify.meta.syntactic.ScalametaTransformer\n      \n      val finder: PathFinder = sourceDirectory.in(in, Compile).value ** \"*.scala\"\n  \n      for(inputFile \u003c- finder.get) yield {\n        val inputStr = IO.read(inputFile)\n        val outputFile = sourceManaged.in(Compile).value / inputFile.name\n        val outputStr = ScalametaTransformer.transform(inputStr)\n        IO.write(outputFile, outputStr)\n        outputFile\n      }\n    }.taskValue,\n    \n    // for import statement and if meta annotation is not expanded\n    libraryDependencies += \"com.github.dmytromitin\" %% \"auxify-meta-core\" % [LATEST VERSION]\n  )\n```\nAnnotated code should be placed in `in/src/main/scala`. Code generation in `out/target/scala-2.13/src_managed/main` can be run with `sbt out/compile`.\n\nExample project is [here](https://github.com/DmytroMitin/scalameta-demo).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmytromitin%2Fauxify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdmytromitin%2Fauxify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmytromitin%2Fauxify/lists"}