diff options
author | Martin Odersky <odersky@gmail.com> | 2011-11-28 13:55:31 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2011-11-28 13:55:31 +0000 |
commit | f69d3e34dd165eb0f3242fcba3e6bbdc3d61e5d1 (patch) | |
tree | 3bd46bb86b0227420d7074553dae68ab16b080f2 | |
parent | 4e987a3cf032eb176c20bf3fd5ac847a73b19c00 (diff) | |
download | scala-f69d3e34dd165eb0f3242fcba3e6bbdc3d61e5d1.tar.gz scala-f69d3e34dd165eb0f3242fcba3e6bbdc3d61e5d1.tar.bz2 scala-f69d3e34dd165eb0f3242fcba3e6bbdc3d61e5d1.zip |
Revised macro defs, added a test case.
-rw-r--r-- | src/compiler/scala/reflect/internal/Flags.scala | 4 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Macros.scala | 29 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Namers.scala | 7 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 5 | ||||
-rw-r--r-- | test/files/pos/macros.flags | 1 | ||||
-rw-r--r-- | test/files/pos/macros.scala | 10 |
7 files changed, 38 insertions, 19 deletions
diff --git a/src/compiler/scala/reflect/internal/Flags.scala b/src/compiler/scala/reflect/internal/Flags.scala index 50d5b5cb82..b95042341a 100644 --- a/src/compiler/scala/reflect/internal/Flags.scala +++ b/src/compiler/scala/reflect/internal/Flags.scala @@ -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 */ @@ -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) diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 05eadb03ae..d0640e76af 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -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)) } /** @@ -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) } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 4c85830311..0f57285480 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -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 } @@ -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?) diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 66a7f90f0a..645d3ecfa0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -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)) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index f9c056e16d..b969e9629f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -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) @@ -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) } @@ -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 diff --git a/test/files/pos/macros.flags b/test/files/pos/macros.flags new file mode 100644 index 0000000000..e1b37447c9 --- /dev/null +++ b/test/files/pos/macros.flags @@ -0,0 +1 @@ +-Xexperimental
\ No newline at end of file diff --git a/test/files/pos/macros.scala b/test/files/pos/macros.scala new file mode 100644 index 0000000000..8a98195978 --- /dev/null +++ b/test/files/pos/macros.scala @@ -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 + } + } +} + + |