Permalink
Browse files

Some type-related fixes and improvements from tmp/globaltypes2

  • Loading branch information...
szeiger committed Sep 1, 2015
1 parent c23e2c7 commit e6acabf7df0a9d90b53d3fd18e6b07b1cc66a3e1
@@ -138,8 +138,8 @@ object GeneratedCodeTest {
def tableName( node:Node ) : String = {
import slick.ast._
node match {
case TableExpansion(generator, tableNode, columns) => tableName(tableNode)
case TableNode(schemaName, tableName, identity, driverTable, _) => tableName
case TableExpansion(_, tableNode, _) => tableName(tableNode)
case t: TableNode => t.tableName
}
}
@@ -240,7 +240,7 @@ trait NullaryNode extends Node {
}
/** An expression that represents a plain value lifted into a Query. */
final case class Pure(value: Node, identity: TypeSymbol = new AnonTypeSymbol) extends UnaryNode with SimplyTypedNode {
final case class Pure(value: Node, identity: TypeSymbol = new AnonTypeSymbol) extends UnaryNode with SimplyTypedNode with TypeGenerator {
type Self = Pure
def child = value
override def childNames = Seq("value")
@@ -348,7 +348,7 @@ object Ordering {
}
/** A .groupBy call. */
final case class GroupBy(fromGen: TermSymbol, from: Node, by: Node, identity: TypeSymbol = new AnonTypeSymbol) extends BinaryNode with DefNode {
final case class GroupBy(fromGen: TermSymbol, from: Node, by: Node, identity: TypeSymbol = new AnonTypeSymbol) extends BinaryNode with DefNode with TypeGenerator {
type Self = GroupBy
def left = from
def right = by
@@ -595,10 +595,10 @@ object FwdPath {
}
/** A Node representing a database table. */
final case class TableNode(schemaName: Option[String], tableName: String, identity: TableIdentitySymbol, driverTable: Any, baseIdentity: TableIdentitySymbol) extends NullaryNode with SimplyTypedNode {
final case class TableNode(schemaName: Option[String], tableName: String, identity: TableIdentitySymbol, baseIdentity: TableIdentitySymbol)(val driverTable: Any) extends NullaryNode with SimplyTypedNode with TypeGenerator {
type Self = TableNode
def buildType = CollectionType(TypedCollectionTypeConstructor.seq, NominalType(identity, UnassignedType))
def rebuild = copy()
def rebuild = copy()(driverTable)
override def getDumpInfo = super.getDumpInfo.copy(name = "Table", mainInfo = schemaName.map(_ + ".").getOrElse("") + tableName)
}
@@ -48,6 +48,11 @@ class AnonSymbol extends TermSymbol {
def name = "@"+System.identityHashCode(this)
}
/** A Node which introduces a NominalType. */
trait TypeGenerator {
def identity: TypeSymbol
}
/** A Node which introduces Symbols. */
trait DefNode extends Node {
def generators: ConstArray[(TermSymbol, Node)]
@@ -17,9 +17,10 @@ class AssignUniqueSymbols extends Phase {
def apply(state: CompilerState) = state.map { tree =>
val seen = new HashSet[AnonSymbol]
def tr(n: Node, replace: Map[AnonSymbol, AnonSymbol]): Node = {
val n2 = n match { // Give TableNode and Pure nodes a unique TypeSymbol
case t: TableNode => t.copy(identity = new AnonTableIdentitySymbol)
val n2 = n match { // Give TableNode, GroupBy and Pure nodes a unique TypeSymbol
case t: TableNode => t.copy(identity = new AnonTableIdentitySymbol)(t.driverTable)
case Pure(value, _) => Pure(value)
case g: GroupBy => g.copy(identity = new AnonTypeSymbol)
case n => n
}
val n3 = n2 match {
@@ -30,8 +30,8 @@ class EmulateOuterJoins(val useLeftJoin: Boolean, val useRightJoin: Boolean) ext
convert(Union(
Join(leftGen, rightGen, left, right, JoinType.Inner, on),
Bind(bgen,
Filter(lgen2, left,
Library.Not.typed(on.nodeType, Library.Exists.typed(on.nodeType, Filter(rgen2, right, on2)))
Filter(lgen2, assignFreshSymbols(left),
Library.Not.typed(on.nodeType, Library.Exists.typed(on.nodeType, Filter(rgen2, assignFreshSymbols(right), on2)))
),
Pure(ProductNode(ConstArray(Ref(bgen), nullStructFor(right.nodeType.structural.asCollectionType.elementType))))
), true).infer())
@@ -51,8 +51,8 @@ class EmulateOuterJoins(val useLeftJoin: Boolean, val useRightJoin: Boolean) ext
convert(Union(
Join(leftGen, rightGen, left, right, JoinType.Left, on),
Bind(bgen,
Filter(rgen2, right,
Library.Not.typed(on.nodeType, Library.Exists.typed(on.nodeType, Filter(lgen2, left, on2)))
Filter(rgen2, assignFreshSymbols(right),
Library.Not.typed(on.nodeType, Library.Exists.typed(on.nodeType, Filter(lgen2, assignFreshSymbols(left), on2)))
),
Pure(ProductNode(ConstArray(nullStructFor(left.nodeType.structural.asCollectionType.elementType), Ref(bgen))))
), true).infer())
@@ -66,4 +66,23 @@ class EmulateOuterJoins(val useLeftJoin: Boolean, val useRightJoin: Boolean) ext
case t: OptionType => LiteralNode(t, None)
case t => LiteralNode(OptionType(t), None)
}
/** Assign new TypeSymbols to a subtree that needs to be copied into multiple places. */
def assignFreshSymbols(n: Node): Node = {
val typeSyms = n.collect { case n: TypeGenerator => n.identity }.toSet
val repl = typeSyms.map {
case ts: TableIdentitySymbol => ts -> new AnonTableIdentitySymbol
case ts => ts -> new AnonTypeSymbol
}.toMap
def replaceTS(t: Type): Type = (t match {
case NominalType(ts, v) => repl.get(ts).map(new NominalType(_, v)).getOrElse(t)
case t => t
}).mapChildren(replaceTS)
//repl.foreach { case (ts1, ts2) => global.get(ts1).foreach(t => global += ts2 -> replaceTS(t)) }
n.replace({
case n: TableNode => n.copy(identity = repl(n.identity).asInstanceOf[TableIdentitySymbol])(n.driverTable) :@ replaceTS(n.nodeType)
case n: Pure => n.copy(identity = repl(n.identity))
case n: GroupBy => n.copy(identity = repl(n.identity))
}, bottomUp = true).infer()
}
}
@@ -34,7 +34,7 @@ class ExpandTables extends Phase {
if(tsyms.isEmpty) tree2 else {
// Find the corresponding TableExpansions
val tables: Map[TableIdentitySymbol, (TermSymbol, Node)] = tree.collect {
case TableExpansion(s, TableNode(_, _, ts, _, _), ex) if tsyms contains ts => ts -> (s, ex)
case TableExpansion(s, TableNode(_, _, ts, _), ex) if tsyms contains ts => ts -> (s, ex)
}.toMap
logger.debug("Table expansions: " + tables.mkString(", "))
// Create a mapping that expands the tables
@@ -41,6 +41,8 @@ class FlattenProjections extends Phase {
n.mapChildren { ch => tr(ch, topLevel && (ch ne n.from)) }
case u: Union =>
n.mapChildren { ch => tr(ch, true) }
case Library.SilentCast(ch) :@ tpe =>
Library.SilentCast.typed(tpe.structuralRec, tr(ch, false))
case n => n.mapChildren(tr(_, false))
}
tr(tree, true).infer()
@@ -10,8 +10,8 @@ class RelabelUnions extends Phase {
val name = "relabelUnions"
def apply(state: CompilerState) = state.map(_.replace({
case u @ Union(Bind(_, _, Pure(StructNode(ls), lts)), rb @ Bind(_, _, Pure(StructNode(rs), _)), _) =>
case u @ Union(Bind(_, _, Pure(StructNode(ls), lts)), rb @ Bind(_, _, Pure(StructNode(rs), rts)), _) =>
val rs2 = ls.zip(rs).map { case ((s, _), (_, n)) => (s, n) }
u.copy(right = rb.copy(select = Pure(StructNode(rs2), lts))).infer()
u.copy(right = rb.copy(select = Pure(StructNode(rs2), rts))).infer()
}, keepType = true, bottomUp = true))
}
@@ -13,7 +13,10 @@ class RemoveFieldNames extends Phase {
val CollectionType(_, NominalType(top, StructType(fdefs))) = rsm.from.nodeType
val indexes = fdefs.iterator.zipWithIndex.map { case ((s, _), i) => (s, ElementSymbol(i+1)) }.toMap
val rsm2 = rsm.nodeMapServerSide(false, { n =>
val refTSyms = n.collect[TypeSymbol] { case Select(_ :@ NominalType(s, _), _) => s }.toSet
val refTSyms = n.collect[TypeSymbol] {
case Select(_ :@ NominalType(s, _), _) => s
case Union(_, _ :@ CollectionType(_, NominalType(s, _)), _) => s
}.toSet
val allTSyms = n.collect[TypeSymbol] { case p: Pure => p.identity }.toSet
val unrefTSyms = allTSyms -- refTSyms
n.replaceInvalidate {
@@ -24,7 +24,7 @@ abstract class AbstractTable[T](val tableTag: Tag, val schemaName: Option[String
def tableIdentitySymbol: TableIdentitySymbol
lazy val tableNode = TableNode(schemaName, tableName, tableIdentitySymbol, this, tableIdentitySymbol)
lazy val tableNode = TableNode(schemaName, tableName, tableIdentitySymbol, tableIdentitySymbol)(this)
def encodeRef(path: Node) = tableTag.taggedAs(path).asInstanceOf[AbstractTable[T]]

0 comments on commit e6acabf

Please sign in to comment.