Skip to content

Commit

Permalink
finishes the codegen
Browse files Browse the repository at this point in the history
  • Loading branch information
xeno-by committed Apr 17, 2015
1 parent 75311c4 commit 3cb0d72
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 6 deletions.
18 changes: 13 additions & 5 deletions foundation/src/main/scala/org/scalameta/ast/ast.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ class AstMacros(val c: Context) {
val iparents1 = ListBuffer[Tree]() ++ iparents
def aparents1 = if (isQuasi) iparents1 else List(tq"$iname")
def parents1 = if (isQuasi) iparents1 else List(tq"$aname")
def iparentsdot(what: String) = iparents1.map({
def iparentsdot(what: String) = iparents1.filter(_.toString != "_root_.scala.Product").map({
case Ident(name) => Select(Ident(name.toTermName), TypeName(what))
case Select(qual, name) => Select(Select(qual, name.toTermName), TypeName(what))
case unsupported => c.abort(unsupported.pos, "implementation restriction: unsupported parent")
})
def uparents1 = tq"_root_.scala.meta.internal.ast.Quasi.Unquote" +: iparentsdot("Unquote")
def eparents1 = tq"_root_.scala.meta.internal.ast.Quasi.Ellipsis" +: iparentsdot("Ellipsis")
def uparents1 = tq"$iname" +: tq"_root_.scala.meta.internal.ast.Quasi.Unquote" +: iparentsdot("Unquote")
def eparents1 = tq"$iname" +: tq"_root_.scala.meta.internal.ast.Quasi.Ellipsis" +: iparentsdot("Ellipsis")
val mstats1 = ListBuffer[Tree]() ++ mstats
val manns1 = ListBuffer[Tree]() ++ mmods.annotations
def mmods1 = mmods.mapAnnotations(_ => manns1.toList)
Expand Down Expand Up @@ -231,6 +231,14 @@ class AstMacros(val c: Context) {
mstats1 += q"@_root_.scala.inline final def unapply(x: $iname): Boolean = true"
}
}

// step 10: finish codegen for Unquote and Ellipsis
ustats1 += q"def pt: _root_.java.lang.Class[_] = _root_.scala.Predef.classOf[$iname]"
estats1 += q"def pt: _root_.java.lang.Class[_] = _root_.org.scalameta.runtime.arrayClass(_root_.scala.Predef.classOf[$iname], rank)"
if (is("Name.Anonymous")) {
ustats1 += q""" def value = "_" """
estats1 += q""" def value = "_" """
}

if (isQuasi) {
val ustats1 = stats1 ++ astats1
Expand All @@ -243,8 +251,8 @@ class AstMacros(val c: Context) {
mstats1 += q"implicit def interfaceToApi(interface: $iname): $aname = macro $AstInternal.Macros.interfaceToApi[$iname, $aname]"
mstats1 += q"trait $aname[..$tparams] extends ..$aparents1 { $aself => ..$astats1 }"
mstats1 += q"private[${mname.toTypeName}] final class $name[..$tparams] $ctorMods(...${bparams1 +: paramss1}) extends { ..$earlydefns } with ..$parents1 { $self => ..$stats1 }"
mstats1 += q"$umods1 class $uname(tree: Any) extends ..$uparents1 { ..$ustats1 }"
mstats1 += q"$emods1 class $ename(tree: _root_.scala.meta.Tree) extends ..$eparents1 { ..$estats1 }"
mstats1 += q"$umods1 class $uname(tree: _root_.scala.Any) extends ..$uparents1 { ..$ustats1 }"
mstats1 += q"$emods1 class $ename(tree: _root_.scala.meta.internal.ast.Tree, rank: _root_.scala.Int) extends ..$eparents1 { ..$estats1 }"
val cdef1 = q"$imods1 trait $iname extends ..$iparents1 { $iself => ..$istats1 }"
val mdef1 = q"$mmods1 object $mname extends { ..$mearlydefns } with ..$mparents { $mself => ..$mstats1 }"
List(cdef1, mdef1)
Expand Down
12 changes: 12 additions & 0 deletions foundation/src/main/scala/org/scalameta/ast/branch.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class BranchMacros(val c: Context) {
val AstInternal = q"_root_.org.scalameta.ast.internal"
def impl(annottees: Tree*): Tree = {
def transform(cdef: ClassDef, mdef: ModuleDef): List[ImplDef] = {
def is(abbrev: String) = c.internal.enclosingOwner.fullName.toString + "." + cdef.name.toString == "scala.meta.internal.ast." + abbrev
def isQuasi = cdef.name.toString == "Quasi" || cdef.name.toString == "Unquote" || cdef.name.toString == "Ellipsis"
val ClassDef(mods @ Modifiers(flags, privateWithin, anns), name, tparams, Template(parents, self, stats)) = cdef
val ModuleDef(mmods, mname, Template(mparents, mself, mstats)) = mdef
val stats1 = ListBuffer[Tree]() ++ stats
Expand All @@ -30,6 +32,16 @@ class BranchMacros(val c: Context) {
mstats1 += q"$AstInternal.hierarchyCheck[$name]"
val anns1 = anns :+ q"new $AdtInternal.branch" :+ q"new $AstInternal.branch"

def parentsdot(what: String) = parents.map({
case Ident(name) => Select(Ident(name.toTermName), TypeName(what))
case Select(qual, name) => Select(Select(qual, name.toTermName), TypeName(what))
case unsupported => c.abort(unsupported.pos, "implementation restriction: unsupported parent")
})
def uparents = tq"$name" +: tq"_root_.scala.meta.internal.ast.Quasi.Unquote" +: parentsdot("Unquote")
def eparents = tq"$name" +: tq"_root_.scala.meta.internal.ast.Quasi.Ellipsis" +: parentsdot("Ellipsis")
if (!isQuasi) mstats1 += q"@_root_.org.scalameta.ast.branch private[meta] trait Unquote extends ..$uparents"
if (!isQuasi) mstats1 += q"@_root_.org.scalameta.ast.branch private[meta] trait Ellipsis extends ..$eparents"

val cdef1 = ClassDef(Modifiers(flags1, privateWithin, anns1), name, tparams, Template(parents, self, stats1.toList))
val mdef1 = ModuleDef(mmods, mname, Template(mparents, mself, mstats1.toList))
List(cdef1, mdef1)
Expand Down
2 changes: 1 addition & 1 deletion foundation/src/main/scala/org/scalameta/ast/internal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ object internal {
import definitions._
def hierarchyCheck[T](implicit T: c.WeakTypeTag[T]): c.Tree = {
val sym = T.tpe.typeSymbol.asClass
val designation = if (sym.isRoot) "root" else if (sym.isBranch) "branch" else if (sym.isLeaf) "leaf" else ???
val designation = if (sym.isRoot) "root" else if (sym.isBranch) "branch" else if (sym.isLeaf) "leaf" else "unknown"
val roots = sym.baseClasses.filter(_.isRoot)
if (roots.length == 0 && sym.isLeaf) c.abort(c.enclosingPosition, s"rootless leaf is disallowed")
else if (roots.length > 1) c.abort(c.enclosingPosition, s"multiple roots for a $designation: " + (roots.map(_.fullName).init.mkString(", ")) + " and " + roots.last.fullName)
Expand Down
3 changes: 3 additions & 0 deletions foundation/src/main/scala/org/scalameta/ast/root.scala
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ class RootMacros(val c: Context) {
private[meta] def internalCopy(prototype: $Tree = internalPrototype, parent: $Tree = internalParent, scratchpad: $Data = internalScratchpad, origin: $Origin = internalOrigin): ThisType
"""
stats1 ++= boilerplate

mstats1 += q"@_root_.org.scalameta.ast.branch private[meta] trait Unquote extends _root_.scala.meta.internal.ast.Quasi.Unquote"
mstats1 += q"@_root_.org.scalameta.ast.branch private[meta] trait Ellipsis extends _root_.scala.meta.internal.ast.Quasi.Ellipsis"

val cdef1 = q"${Modifiers(flags1, privateWithin, anns1)} trait $name[..$tparams] extends { ..$earlydefns } with ..$parents1 { $self => ..$stats1 }"
val mdef1 = q"$mmods object $mname extends { ..$mearlydefns } with ..$mparents { $mself => ..$mstats1 }"
Expand Down
11 changes: 11 additions & 0 deletions foundation/src/main/scala/org/scalameta/runtime/package.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.scalameta

import scala.runtime.ScalaRunTime

package object runtime {
def arrayClass(clazz: Class[_], rank: Int): Class[_] = {
Predef.require(rank > 0)
if (rank == 1) ScalaRunTime.arrayClass(clazz)
else arrayClass(ScalaRunTime.arrayClass(clazz), rank - 1)
}
}
1 change: 1 addition & 0 deletions scalameta/src/main/scala/scala/meta/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,7 @@ package scala.meta.internal.ast {
// pt being Array[T] means rank 1 means .., pt being Array[Array[T]] means rank 2 means ..., etc
@branch trait Ellipsis extends Quasi {
def tree: Tree
def rank: Int
def pt: Class[_]
require(pt.isArray)
}
Expand Down

0 comments on commit 3cb0d72

Please sign in to comment.