by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Stefan Wachter
    @swachter
    I started studying the mdoc-plugin. Maybe I find all information in there. Thanks for the point @olafurpg .
    Ólafur Páll Geirsson
    @olafurpg
    @swachter the mdoc plugin should give you an idea of how it works
    the sbt-mdoc plugin adds a resource generator to persist the project's classpath
    and the mdoc task runs the mdoc Main method
    the mdoc command-line tool then reads the project's classpath via the generated resource file
    Stefan Wachter
    @swachter
    @olafurpg Great that some smart persons have already figured out how to set everything up!
    I have a small detail problem: the SBT plugin allows to configure the scala.meta.Dialect of the parsed sources. How would you pass that information via the properties file into the generator? Json would be a possiblity, but maybe there is already something included in ScalaMeta? Dialect seems to be a generated class.
    Ólafur Páll Geirsson
    @olafurpg
    @swachter Dialect is just a normal class in the latest scalameta version
    otherwise you don't really need to worry about the dialect I think if you use Scala213 by default
    it won't cause issues to use Scala213 in 2.12 projects
    Stefan Wachter
    @swachter

    @olafurpg After everything is in place I get

    runMain is not supported in Scala.js

    I fear I have to go into the guts of SBT.

    Ólafur Páll Geirsson
    @olafurpg
    @swachter you can alternatively fork a new JVM process
    you have the full classpath of the project
    Stefan Wachter
    @swachter
    Ok. Forking migth be easier than to struggle with project setup. Will have a look.
    Ólafur Páll Geirsson
    @olafurpg
    fullClasspath.value.map(_.data) will give you all the classpath entries
    sbt has some utilities to fork processes
    Stefan Wachter
    @swachter
    @olafurpg Success!!! Many thanks for your help!
    Ólafur Páll Geirsson
    @olafurpg
    \o/ :tada:
    Stefan Wachter
    @swachter

    @olafurpg Is there a principled way to translate symbols of ScalaMeta into "fullName"s that are used in scala reflection? For example the symbol

    scala.scalajs.js.`|`

    should be translated into

    scala.scalajs.js.$bar
    Ólafur Páll Geirsson
    @olafurpg
    @swachter scala.reflect.NameTransformer.encode("|")
    If you only need this functionality for toplevel symbols then that should do the trick
    Stefan Wachter
    @swachter
    @olafurpg Many thanks! Toplevel symbols should suffice.
    Stefan Wachter
    @swachter

    @olafurpg Toplevel symbols do no more suffice. After ScalaJS now supports nested objects (since the newly released v 1.1.1) I have to access annotation information for these nested objects too. In particular I have the following structure:

    object Outer {
      class Middle {
        object Inner
      }
    }

    Its symbol is:

    eu/swdev/scala/ts/dts/Outer.Middle#Inner.

    I have no clue how to access the annotations of object Inner. I can get the TypeSymbolApi of Outer by calling mirror.staticModule(...).moduleClass.asClass. It is also possible to get the TypeSymbolApi of Middle by calling mirror.staticClass(...). But how to get to its member Inner?

    Stefan Wachter
    @swachter
    I wrote an implementation to get a scala-reflect TypeSymbolApi given a Scalameta symbol. However, it seems to be crazy:
      def transform(sym: String): String = NameTransformer.encode(sym.replace("`", ""))
    
      private def symbolInformation2TypeSymbolApi(si: SymbolInformation): TypeSymbolApi = {
        import scala.collection.JavaConverters._
    
        val splitted = si.symbol.split('/')
        val pckg     = splitted.dropRight(1).mkString(".")
        val nested   = new StringTokenizer(splitted.last, ".#", true).asScala.grouped(2).map(_.mkString("")).toList
    
        val objectPrefix = nested.takeWhile(_.endsWith("."))
        val objectSuffix = nested.dropWhile(_.endsWith("."))
    
        val (prefix, suffix) = objectSuffix match {
          case head :: tail => (objectPrefix :+ head, tail)
          case _            => (objectPrefix, Nil)
        }
    
        val outerName     = prefix.map(s => transform(s.dropRight(1))).mkString(".")
        val fullOuterName = s"$pckg.$outerName"
        var tsa: TypeSymbolApi = if (prefix.last.endsWith(".")) {
          mirror.staticModule(fullOuterName).moduleClass.asClass
        } else {
          mirror.staticClass(fullOuterName)
        }
    
        var tail = suffix
        while (tail.nonEmpty) {
          val head      = tail.head
          val innerName = transform(head.dropRight(1))
          if (head.endsWith(".")) {
            val o = tsa.toType.decls.find(sym => sym.isModule && sym.name.decoded == innerName)
            tsa = o.get.asModule.moduleClass.asClass
          } else {
            val o = tsa.toType.decls.find(sym => sym.isClass && sym.name.decoded == innerName)
            tsa = o.get.asClass
          }
          tail = tail.tail
        }
    
        tsa
      }
    Stefan Wachter
    @swachter
    Can you please publish the semanticdb-scalac plugin for Scala 2.13.3?
    Ólafur Páll Geirsson
    @olafurpg
    @swachter If you don't mind using scala-compiler you can re-use the logic to convert from SemanticDB to compiler symbols here https://github.com/scalacenter/scalafix/blob/b8667ef7e1e2fa81251765d46547d585564ebb0a/scalafix-rules/src/main/scala/scala/meta/internal/pc/ScalafixGlobal.scala#L60
    semanticdb-scalac is already published for 2.13.3
    cs complete org.scalameta:semanticdb-scalac_2.13.3:
    4.3.16
    4.3.17
    4.3.18
    Stefan Wachter
    @swachter
    @olafurpg Ah, ok. I still used 4.3.10. I will update to 4.3.18. I will have a look on that code. First impression: it is also somewhat involved.
    Stefan Wachter
    @swachter
    Is it possible to enable the semanticdb compiler plugin for the test configuration only? (My library contains some test that are base on semanticdb files, but do not want to include semantic db files in the published library artifact.)
    Dmytro Mitin
    @DmytroMitin
    @swachter Would it be better to use scala.meta.interactive.InteractiveSemanticdb?
    Stefan Wachter
    @swachter
    @DmytroMitin Thanks for the pointer. Didn't know about InteractiveSemanticdb. May use it for "plan b".
    nafg
    @nafg
    Hi, what exactly is Init#name?
    Dmytro Mitin
    @DmytroMitin
    @nafg Name.Anonymous()
    q"""class A extends B(1, "a") with C""" match {
      case q"""..$mods class $tname[..$tparams] ..$ctorMods (...$paramss) extends ${
        template"""{ ..$stats } with ..$inits { $self => ..$stats1 }"""}""" =>
          inits.foreach {
            case init@init"$tpe(...$exprss)" =>
              init.name match {
                case Name.Anonymous() => println("matches")
              }
          }
    }
    
    q"""new A(1, "a")""" match {
      case q"new ${init@init"$tpe(...$exprss)"}" =>
        init.name match {
          case Name.Anonymous() => println("matches")
        }
    }
    nafg
    @nafg
    @DmytroMitin if it has to be anonymous why does it exist?
    fwiw I realized to use Name.Anonymous() from AST explorer
    Dmytro Mitin
    @DmytroMitin

    @nafg Read sources
    https://github.com/scalameta/scalameta/blob/master/scalameta/trees/shared/src/main/scala/scala/meta/Trees.scala#L441-L443

    // NOTE: The name here is always Name.Anonymous.
    // See comments to Ctor.Primary and Ctor.Secondary for justification.
    @ast class Init(tpe: Type, name: Name, argss: List[List[Term]]) extends Ref {

    https://github.com/scalameta/scalameta/blob/master/scalameta/trees/shared/src/main/scala/scala/meta/Trees.scala#L424-L427

    // NOTE: The names of Ctor.Primary and Ctor.Secondary here is always Name.Anonymous.
    // While seemingly useless, this name is crucial to one of the key principles behind the semantic API:
    // "every definition and every reference should carry a name".
    @branch trait Ctor extends Tree with Member
    nafg
    @nafg
    @DmytroMitin thanks!
    Why is that a key principle?
    In any case, couldn't they make the type of name Name.Anonymous since that's the only value it makes sense to have?
    Dave Nicponski
    @virusdave
    heyas all - are quasiquotes in scope for this room ?
    Dave Nicponski
    @virusdave

    just in case... It looks to me that the classfiles generated by macros that use quasiquotes are nondeterministic (at least in 2.11.x). Decompiling a classfile, i see local var tables that look like:

     92     121     6 qq$9bc364f6$macro$3   Lscala/reflect/api/Trees$TreeApi;

    for pattern match cases. Note the address which has leaked in there. Is this expected?

    i ask because we're using these in a very very core logging library, and this nondeterminism in output actually causes rippling cache missed (we use bazel to build a large codebase), basically causing everything to recompile often. I haven't yet found why this happens by reading the quasiquote source code, so maybe it's been fixed already?
    Has anyone else seen this before? Is there any mitigation we can apply other than just not using QQs?
    Ólafur Páll Geirsson
    @olafurpg
    @virusdave scalameta is unrelated to macros so this is not the right channel.
    I think the latest 2.12 releases have fixed related to determinism which were implemented exactly to improve the situation for Bazel. I’m not sure if those changes got backported for 2.11
    Dave Nicponski
    @virusdave
    Thanks, i'll head over to scala/scala then i guess! :)
    Ólafur Páll Geirsson
    @olafurpg
    I’m a bit surprised that Bazel includes anonymous classes in ijars given they’re an implementation detail and can’t be accessed from client code
    @virusdave if upgrading to 2.12 is not an option then it might be worth exploring whether it’s possible to leave our anonymous classes from ijars