Skip to content

Commit

Permalink
findMember of RefinedTypes
Browse files Browse the repository at this point in the history
  • Loading branch information
tanishiking committed Jun 23, 2021
1 parent 37d8d6c commit ebdf900
Showing 1 changed file with 56 additions and 23 deletions.
79 changes: 56 additions & 23 deletions compiler/src/dotty/tools/dotc/semanticdb/SymbolOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ object SymbolOps:
extension (sym: Symbol)
def sig(using LinkMode, Context): s.Signature =
import TypeOps._
println("")
println(sym.toString)
println(s"=========sym.info================")
pprint.pprintln(sym.info)
val sig = sym.info.toSemanticSig(sym)
// println("")
// println(sym.toString)
// println(s"=========sym.info================")
// pprint.pprintln(sym.info)
// pprint.pprintln(sig)
println(s"=========sig================")
pprint.pprintln(sig)
sig

object TypeOps:
Expand All @@ -35,16 +36,16 @@ object TypeOps:
s.MethodSignature(
stparams,
sparamss,
mt.resType.toSemanticType
mt.resType.toSemanticType(sym)
)

case cls: ClassInfo =>
val stparams =
if (cls.cls.typeParams.nonEmpty)
Some(cls.cls.typeParams.sscope)
else None
val sparents = cls.parents.map(_.toSemanticType)
val sself = cls.selfType.toSemanticType
val sparents = cls.parents.map(_.toSemanticType(sym))
val sself = cls.selfType.toSemanticType(sym)
val decls = cls.decls.toList.sscope(using LinkMode.HardlinkChildren)
s.ClassSignature(stparams, sparents, sself, Some(decls))

Expand All @@ -53,8 +54,8 @@ object TypeOps:
// type Poly[T] = List[T] is equivalent with
// type Poly = [T] =>> List[T]
val stparams = Some(s.Scope())
val slo = lo.toSemanticType
val shi = hi.toSemanticType
val slo = lo.toSemanticType(sym)
val shi = hi.toSemanticType(sym)
s.TypeSignature(stparams, slo, shi)

case pt: PolyType =>
Expand All @@ -72,12 +73,12 @@ object TypeOps:

case other =>
s.ValueSignature(
other.toSemanticType
other.toSemanticType(sym)
)
}
loop(tpe)

private def toSemanticType(using LinkMode, Context): s.Type =
private def toSemanticType(using LinkMode)(using ctx: Context)(sym: Symbol): s.Type =
import ConstantOps._
def loop(tpe: Type): s.Type = tpe match {
case ExprType(tpe) =>
Expand All @@ -94,9 +95,22 @@ object TypeOps:
val ssym = symbolName(desig.asInstanceOf[Symbol])
s.SingleType(spre, ssym)

// TODO: TypeParamRef and TermParamRef
// but how can we retrieve their symbols? (for representing them as TypeRef and TermRef on Semanticdb)
// or should we add new types to Semanticdb
case tref: TypeParamRef =>
// println(s"rawParamss: ${sym.rawParamss}")
// println(s"num: ${tref.paramNum}, name: ${tref.paramName}")
val paramref = sym.rawParamss.flatMap { params =>
if (params.length > tref.paramNum) Some(params(tref.paramNum))
else None
}.find(p => p.name == tref.paramName)
paramref match {
case Some(ref) =>
val ssym = symbolName(ref)
s.TypeRef(s.Type.Empty, ssym, Seq.empty)
case None => // shouldn't happen
s.Type.Empty
}

// TODO: TermParamRef

case ThisType(TypeRef(_, desig)) if desig.isInstanceOf[Symbol] =>
val ssym = symbolName(desig.asInstanceOf[Symbol])
Expand Down Expand Up @@ -125,22 +139,41 @@ object TypeOps:
// refinedName = x
// refinedInfo = TypeRef(..., Int)
// )
def getParent(parent: Type): Type = parent match {
case RefinedType(p, _, _) => getParent(p)
case _ => parent

type RefinedInfo = (core.Names.Name, Type)
def flatten(tpe: Type, acc: List[RefinedInfo]): (Type, List[RefinedInfo]) = tpe match {
case RefinedType(parent, name, info) =>
flatten(parent, acc :+ (name, info))
case _ =>
(tpe, acc)
}
val (parent, refinedInfos) = flatten(rt, List.empty)

val realParent = getParent(parent)
val stpe = realParent match {
val stpe = parent match {
// val tp: M with N { def k: Int } = ???
case AndType(x, y) =>
s.WithType(Seq(loop(x), loop(y))) // TODO: for M with N with L
case _ =>
s.WithType(Seq(loop(parent)))
}
// TODO: collect all refinement symbols
// val sdecls = decls.sscope(using LinkMode.HardlinkChildren)
s.StructuralType(stpe, None)
val decls = for {
(name, info) <- refinedInfos
} yield {
// do we need this?
// isLegalPrefix returns true outside in typer
val pre = ctx.typeAssigner.maybeSkolemizePrefix(rt, name)
val denot = rt.findMember(name, pre)
// assert(denot.info eq info, s"(${denot.info.show}) is not eq to (${info.show})")
println(s"denot.info: ${denot.info}, info: ${info}, sym: ${denot.symbol}")
val sym =
if denot.symbol.exists then
println(s"refined ${denot.symbol.show} with ${info.show}")
denot.symbol
else ???
sym
}
val sdecls = decls.sscope(using LinkMode.HardlinkChildren)
s.StructuralType(stpe, Some(sdecls))

case rec: RecType =>
loop(rec.parent) // should be handled as RefinedType
Expand Down

0 comments on commit ebdf900

Please sign in to comment.