Skip to content

Commit

Permalink
Revised macro defs, added a test case.
Browse files Browse the repository at this point in the history
  • Loading branch information
odersky committed Nov 28, 2011
1 parent 4e987a3 commit f69d3e3
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 19 deletions.
4 changes: 2 additions & 2 deletions src/compiler/scala/reflect/internal/Flags.scala
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ class Flags extends ModifierFlags {

/** These modifiers appear in TreePrinter output. */
final val PrintableFlags: Long =
ExplicitFlags | LOCAL | SYNTHETIC | STABLE | CASEACCESSOR |
ExplicitFlags | LOCAL | SYNTHETIC | STABLE | CASEACCESSOR | MACRO |
ACCESSOR | SUPERACCESSOR | PARAMACCESSOR | BRIDGE | STATIC | VBRIDGE | SPECIALIZED

/** The two bridge flags */
Expand Down Expand Up @@ -352,7 +352,7 @@ class Flags extends ModifierFlags {
case MUTABLE => "<mutable>" // (1L << 12)
case PARAM => "<param>" // (1L << 13)
case PACKAGE => "<package>" // (1L << 14)
case 0x8000L => "" // (1L << 15)
case MACRO => "macro" // (1L << 15)
case BYNAMEPARAM => "<bynameparam/captured/covariant>" // (1L << 16)
case CONTRAVARIANT => "<contravariant/inconstructor/label>" // (1L << 17)
case ABSOVERRIDE => "absoverride" // (1L << 18)
Expand Down
29 changes: 16 additions & 13 deletions src/compiler/scala/tools/nsc/typechecker/Macros.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ trait Macros { self: Analyzer =>
import global._
import definitions._

def macroMethName(name: Name) =
newTermName((if (name.isTypeName) "type" else "def") + "macro$" + name)
def macroMethName(sym: Symbol) =
newTermName((if (sym.name.isTypeName) "type" else "def") + "macro$" +
(if (sym.owner.isModuleClass) "obj$" else "cls$") + sym.name)

def macroMeth(mac: Symbol): Symbol = {
var owner = mac.owner
if (!owner.isModuleClass) owner = owner.companionModule.moduleClass
owner.info.decl(macroMethName(mac.name))
owner.info.decl(macroMethName(mac))
}

/**
Expand Down Expand Up @@ -46,20 +47,22 @@ trait Macros { self: Analyzer =>
Block(List(ValDef(Modifiers(IMPLICIT), "$glob", universeType, Ident("glob"))), tree)
}

treeCopy.DefDef(
mdef,
mods = mdef.mods &~ MACRO,
name = mdef.name.toTermName,
tparams = List(),
vparamss = List(globParam) :: List(thisParam) :: (mdef.tparams map tparamInMacro) ::
(mdef.vparamss map (_ map vparamInMacro)),
tpt = globTree,
wrapImplicit(mdef.rhs))
atPos(mdef.pos) {
new DefDef( // can't call DefDef here; need to find out why
mods = mdef.mods &~ MACRO,
name = macroMethName(mdef.symbol),
tparams = List(),
vparamss = List(globParam) :: List(thisParam) :: (mdef.tparams map tparamInMacro) ::
(mdef.vparamss map (_ map vparamInMacro)),
tpt = globTree,
wrapImplicit(mdef.rhs))
}
}

def addMacroMethods(templ: Template, namer: Namer): Unit = {
for (ddef @ DefDef(mods, _, _, _, _, _) <- templ.body if mods hasFlag MACRO) {
namer.enterSyntheticSym(macroMethDef(ddef))
val sym = namer.enterSyntheticSym(util.trace("macro def: ")(macroMethDef(ddef)))
println("added to "+namer.context.owner.enclClass+": "+sym)
}
}

Expand Down
7 changes: 5 additions & 2 deletions src/compiler/scala/tools/nsc/typechecker/Namers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -783,8 +783,11 @@ trait Namers extends MethodSynthesis {
val typedBody = defnTyper.computeType(tree.rhs, pt)
val sym = if (owner.isMethod) owner else tree.symbol
val typedDefn = widenIfNecessary(sym, typedBody, pt)
assignTypeToTree(tree, typedDefn)
}

tree.tpt defineType typedDefn setPos tree.pos.focus
private def assignTypeToTree(tree: ValOrDefDef, tpe: Type): Type = {
tree.tpt defineType tpe setPos tree.pos.focus
tree.tpt.tpe
}

Expand Down Expand Up @@ -1003,7 +1006,7 @@ trait Namers extends MethodSynthesis {
if (!tpt.isEmpty) {
typer.typedType(tpt).tpe
} else if (meth.isMacro) {
AnyClass.tpe
assignTypeToTree(ddef, AnyClass.tpe)
} else {
// replace deSkolemized symbols with skolemized ones
// (for resultPt computed by looking at overridden symbol, right?)
Expand Down
1 change: 1 addition & 0 deletions src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1225,6 +1225,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
List(tree1)
}
case Import(_, _) => Nil
case DefDef(mods, _, _, _, _, _) if (mods hasFlag MACRO) => Nil
case _ => List(transform(tree))
}

Expand Down
5 changes: 3 additions & 2 deletions src/compiler/scala/tools/nsc/typechecker/Typers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1676,7 +1676,6 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
*/
def typedDefDef(ddef: DefDef): DefDef = {
val meth = ddef.symbol.initialize
if (meth.isMacro) return ddef

reenterTypeParams(ddef.tparams)
reenterValueParams(ddef.vparamss)
Expand Down Expand Up @@ -1712,6 +1711,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
meth.owner.isAnonOrRefinementClass))
error(ddef.pos, "constructor definition not allowed here")
typed(ddef.rhs)
} else if (meth.isMacro) {
EmptyTree
} else {
transformedOrTyped(ddef.rhs, EXPRmode, tpt1.tpe)
}
Expand Down Expand Up @@ -3444,7 +3445,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
// (calling typed1 more than once for the same tree)
if (checked ne res) typed { atPos(tree.pos)(checked) }
else res
} else if (fun2.hasSymbol && fun2.symbol.isMacro)
} else if ((mode & FUNmode) == 0 && fun2.hasSymbol && fun2.symbol.isMacro)
typed1(macroExpand(res), mode, pt)
else
res
Expand Down
1 change: 1 addition & 0 deletions test/files/pos/macros.flags
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-Xexperimental
10 changes: 10 additions & 0 deletions test/files/pos/macros.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
object Test {

class C {
def macro foo[T](xs: List[T]): T = (T, xs) match {
case (t1: glob.Type, t2: glob.Tree) => t2
}
}
}


0 comments on commit f69d3e3

Please sign in to comment.