Skip to content

Commit 1e8c8a6

Browse files
authored
Merge pull request #3634 from dotty-staging/add-meta
A symmetric meta programming framework
2 parents 0cdc425 + 8f048a7 commit 1e8c8a6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1919
-245
lines changed

compiler/src/dotty/tools/dotc/CompilationUnit.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ class CompilationUnit(val source: SourceFile) {
2121

2222
/** Pickled TASTY binaries, indexed by class. */
2323
var pickled: Map[ClassSymbol, Array[Byte]] = Map()
24+
25+
/** Will be reset to `true` if `untpdTree` contains `Quote` trees. The information
26+
* is used in phase ReifyQuotes in order to avoid traversing a quote-less tree.
27+
*/
28+
var containsQuotesOrSplices: Boolean = false
2429
}
2530

2631
object CompilationUnit {

compiler/src/dotty/tools/dotc/Compiler.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,10 @@ class Compiler {
4747
List(new sbt.ExtractAPI), // Sends a representation of the API of classes to sbt via callbacks
4848
List(new Pickler), // Generate TASTY info
4949
List(new LinkAll), // Reload compilation units from TASTY for library code (if needed)
50+
List(new ReifyQuotes), // Turn quoted trees into explicit run-time data structures
5051
List(new FirstTransform, // Some transformations to put trees into a canonical form
5152
new CheckReentrant, // Internal use only: Check that compiled program has no data races involving global vars
52-
new ElimJavaPackages), // Eliminate syntactic references to Java packages
53+
new ElimPackagePrefixes), // Eliminate references to package prefixes in Select nodes
5354
List(new CheckStatic, // Check restrictions that apply to @static members
5455
new ElimRepeated, // Rewrite vararg parameters and arguments
5556
new NormalizeFlags, // Rewrite some definition flags
@@ -59,16 +60,16 @@ class Compiler {
5960
new ByNameClosures, // Expand arguments to by-name parameters to closures
6061
new LiftTry, // Put try expressions that might execute on non-empty stacks into their own methods
6162
new HoistSuperArgs, // Hoist complex arguments of supercalls to enclosing scope
62-
new ClassOf, // Expand `Predef.classOf` calls.
63-
new RefChecks), // Various checks mostly related to abstract members and overriding
63+
new ClassOf, // Expand `Predef.classOf` calls.
64+
new RefChecks), // Various checks mostly related to abstract members and overriding
6465
List(new TryCatchPatterns, // Compile cases in try/catch
6566
new PatternMatcher, // Compile pattern matches
6667
new ExplicitOuter, // Add accessors to outer classes from nested ones.
6768
new ExplicitSelf, // Make references to non-trivial self types explicit as casts
6869
new ShortcutImplicits, // Allow implicit functions without creating closures
6970
new CrossCastAnd, // Normalize selections involving intersection types.
7071
new Splitter), // Expand selections involving union types into conditionals
71-
List(new PhantomArgLift, // Extracts the evaluation of phantom arguments placing them before the call.
72+
List(new PhantomArgLift, // Extracts the evaluation of phantom arguments placing them before the call.
7273
new VCInlineMethods, // Inlines calls to value class methods
7374
new SeqLiterals, // Express vararg arguments as arrays
7475
new InterceptedMethods, // Special handling of `==`, `|=`, `getClass` methods

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1069,7 +1069,8 @@ object desugar {
10691069
Select(t, op.name)
10701070
}
10711071
case PrefixOp(op, t) =>
1072-
Select(t, nme.UNARY_PREFIX ++ op.name)
1072+
val nspace = if (ctx.mode.is(Mode.Type)) tpnme else nme
1073+
Select(t, nspace.UNARY_PREFIX ++ op.name)
10731074
case Tuple(ts) =>
10741075
val arity = ts.length
10751076
def tupleTypeRef = defn.TupleType(arity)

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ trait UntypedTreeInfo extends TreeInfo[Untyped] { self: Trees.Instance[Untyped]
264264
*/
265265
def lacksDefinition(mdef: MemberDef)(implicit ctx: Context) = mdef match {
266266
case mdef: ValOrDefDef =>
267-
mdef.unforcedRhs == EmptyTree && !mdef.name.isConstructorName && !mdef.mods.is(ParamAccessor)
267+
mdef.unforcedRhs == EmptyTree && !mdef.name.isConstructorName && !mdef.mods.is(TermParamOrAccessor)
268268
case mdef: TypeDef =>
269269
def isBounds(rhs: Tree): Boolean = rhs match {
270270
case _: TypeBoundsTree => true

compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import dotty.tools.dotc.transform.SymUtils._
3131
* gets two different denotations in the same period. Hence, if -Yno-double-bindings is
3232
* set, we would get a data race assertion error.
3333
*/
34-
final class TreeTypeMap(
34+
class TreeTypeMap(
3535
val typeMap: Type => Type = IdentityTypeMap,
3636
val treeMap: tpd.Tree => tpd.Tree = identity _,
3737
val oldOwners: List[Symbol] = Nil,
@@ -154,7 +154,7 @@ final class TreeTypeMap(
154154
assert(!to.exists(substFrom contains _))
155155
assert(!from.exists(newOwners contains _))
156156
assert(!to.exists(oldOwners contains _))
157-
new TreeTypeMap(
157+
newMap(
158158
typeMap,
159159
treeMap,
160160
from ++ oldOwners,
@@ -163,6 +163,16 @@ final class TreeTypeMap(
163163
to ++ substTo)
164164
}
165165

166+
/** A new map of the same class this one */
167+
protected def newMap(
168+
typeMap: Type => Type,
169+
treeMap: Tree => Tree,
170+
oldOwners: List[Symbol],
171+
newOwners: List[Symbol],
172+
substFrom: List[Symbol],
173+
substTo: List[Symbol])(implicit ctx: Context) =
174+
new TreeTypeMap(typeMap, treeMap, oldOwners, newOwners, substFrom, substTo)
175+
166176
/** Apply `typeMap` and `ownerMap` to given symbols `syms`
167177
* and return a treemap that contains the substitution
168178
* between original and mapped symbols.

compiler/src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
104104
Closure(Nil, call, targetTpt))
105105
}
106106

107+
/** A closure whole anonymous function has the given method type */
108+
def Lambda(tpe: MethodType, rhsFn: List[Tree] => Tree)(implicit ctx: Context): Block = {
109+
val meth = ctx.newSymbol(ctx.owner, nme.ANON_FUN, Synthetic | Method, tpe)
110+
Closure(meth, tss => rhsFn(tss.head).changeOwner(ctx.owner, meth))
111+
}
112+
107113
def CaseDef(pat: Tree, guard: Tree, body: Tree)(implicit ctx: Context): CaseDef =
108114
ta.assignType(untpd.CaseDef(pat, guard, body), body)
109115

compiler/src/dotty/tools/dotc/ast/untpd.scala

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,10 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
6969

7070
case class InfixOp(left: Tree, op: Ident, right: Tree) extends OpTree
7171
case class PostfixOp(od: Tree, op: Ident) extends OpTree
72-
case class PrefixOp(op: Ident, od: Tree) extends OpTree
72+
case class PrefixOp(op: Ident, od: Tree) extends OpTree {
73+
override def isType = op.isType
74+
override def isTerm = op.isTerm
75+
}
7376
case class Parens(t: Tree) extends ProxyTree {
7477
def forwardTo = t
7578
}
@@ -78,6 +81,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
7881
override def isType = !isTerm
7982
}
8083
case class Throw(expr: Tree) extends TermTree
84+
case class Quote(expr: Tree) extends TermTree
8185
case class WhileDo(cond: Tree, body: Tree) extends TermTree
8286
case class DoWhile(body: Tree, cond: Tree) extends TermTree
8387
case class ForYield(enums: List[Tree], expr: Tree) extends TermTree
@@ -449,6 +453,10 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
449453
case tree: Throw if expr eq tree.expr => tree
450454
case _ => finalize(tree, untpd.Throw(expr))
451455
}
456+
def Quote(tree: Tree)(expr: Tree) = tree match {
457+
case tree: Quote if expr eq tree.expr => tree
458+
case _ => finalize(tree, untpd.Quote(expr))
459+
}
452460
def WhileDo(tree: Tree)(cond: Tree, body: Tree) = tree match {
453461
case tree: WhileDo if (cond eq tree.cond) && (body eq tree.body) => tree
454462
case _ => finalize(tree, untpd.WhileDo(cond, body))
@@ -507,6 +515,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
507515
cpy.Tuple(tree)(transform(trees))
508516
case Throw(expr) =>
509517
cpy.Throw(tree)(transform(expr))
518+
case Quote(expr) =>
519+
cpy.Quote(tree)(transform(expr))
510520
case WhileDo(cond, body) =>
511521
cpy.WhileDo(tree)(transform(cond), transform(body))
512522
case DoWhile(body, cond) =>
@@ -554,6 +564,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
554564
this(x, trees)
555565
case Throw(expr) =>
556566
this(x, expr)
567+
case Quote(expr) =>
568+
this(x, expr)
557569
case WhileDo(cond, body) =>
558570
this(this(x, cond), body)
559571
case DoWhile(body, cond) =>

compiler/src/dotty/tools/dotc/config/Printers.scala

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,27 @@ object Printers {
1111
}
1212

1313
val default: Printer = new Printer
14-
val dottydoc: Printer = noPrinter
15-
val core: Printer = noPrinter
16-
val typr: Printer = noPrinter
14+
1715
val constr: Printer = noPrinter
16+
val core: Printer = noPrinter
1817
val checks: Printer = noPrinter
19-
val overload: Printer = noPrinter
20-
val implicits: Printer = noPrinter
21-
val implicitsDetailed: Printer = noPrinter
22-
val subtyping: Printer = noPrinter
23-
val unapp: Printer = noPrinter
24-
val gadts: Printer = noPrinter
25-
val hk: Printer = noPrinter
26-
val variances: Printer = noPrinter
27-
val incremental: Printer = noPrinter
2818
val config: Printer = noPrinter
29-
val transforms: Printer = noPrinter
3019
val cyclicErrors: Printer = noPrinter
31-
val pickling: Printer = noPrinter
32-
val inlining: Printer = noPrinter
20+
val dottydoc: Printer = noPrinter
3321
val exhaustivity: Printer = noPrinter
22+
val incremental: Printer = noPrinter
23+
val gadts: Printer = noPrinter
24+
val hk: Printer = noPrinter
25+
val implicits: Printer = noPrinter
26+
val implicitsDetailed: Printer = noPrinter
27+
val inlining: Printer = noPrinter
28+
val overload: Printer = noPrinter
3429
val patmatch: Printer = noPrinter
30+
val pickling: Printer = noPrinter
3531
val simplify: Printer = noPrinter
32+
val subtyping: Printer = noPrinter
33+
val transforms: Printer = noPrinter
34+
val typr: Printer = noPrinter
35+
val unapp: Printer = noPrinter
36+
val variances: Printer = noPrinter
3637
}

compiler/src/dotty/tools/dotc/core/Contexts.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,15 @@ object Contexts {
359359
else if (untpd.isSuperConstrCall(stat) && this.owner.isClass) superCallContext
360360
else ctx.fresh.setOwner(exprOwner)
361361

362+
/** A new context that summarizes an import statement */
363+
def importContext(imp: Import[_], sym: Symbol) = {
364+
val impNameOpt = imp.expr match {
365+
case ref: RefTree[_] => Some(ref.name.asTermName)
366+
case _ => None
367+
}
368+
ctx.fresh.setImportInfo(new ImportInfo(implicit ctx => sym, imp.selectors, impNameOpt))
369+
}
370+
362371
/** The current source file; will be derived from current
363372
* compilation unit.
364373
*/

compiler/src/dotty/tools/dotc/core/Decorators.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,10 @@ object Decorators {
175175
recur(enclosingInlineds, pos)
176176
}
177177

178+
implicit class reportingDeco[T](val x: T) extends AnyVal {
179+
def reporting(op: T => String): T = { println(op(x)); x }
180+
}
181+
178182
implicit class StringInterpolators(val sc: StringContext) extends AnyVal {
179183

180184
/** General purpose string formatting */

0 commit comments

Comments
 (0)