Skip to content

Commit

Permalink
Generate dummy symbols for refinements
Browse files Browse the repository at this point in the history
  • Loading branch information
tanishiking committed Jun 23, 2021
1 parent ebdf900 commit a46e4c7
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,18 +93,22 @@ object SemanticSymbolBuilder:
*/
def localIdx(sym: Symbol)(using Context): Int =
val startPos =
assert(sym.span.exists, s"$sym should have a span")
sym.span.start
if sym.span.exists then Some(sym.span.start) else None
// assert(sym.span.exists, s"$sym should have a span")
@tailrec
def computeLocalIdx(sym: Symbol): Int = locals get sym match
case Some(idx) => idx
case None => symsAtOffset(startPos).find(_.name == sym.name) match
case None => (for {
pos <- startPos
samePosSyms <- symsAtOffset.get(pos)
sameName <- samePosSyms.find(_.name == sym.name)
} yield sameName) match
case Some(other) => computeLocalIdx(other)
case None =>
val idx = nextLocalIdx
nextLocalIdx += 1
locals(sym) = idx
symsAtOffset(startPos) += sym
startPos.foreach(pos => symsAtOffset(pos) += sym)
idx
end computeLocalIdx
computeLocalIdx(sym)
Expand Down
57 changes: 28 additions & 29 deletions compiler/src/dotty/tools/dotc/semanticdb/SymbolOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import core.Symbols._
import core.Contexts.Context
import core.Types._
import core.Annotations.Annotation
import core.Flags.EmptyFlags
import ast.tpd._

import dotty.tools.dotc.{semanticdb => s}
Expand All @@ -16,11 +17,11 @@ object SymbolOps:
extension (sym: Symbol)
def sig(using LinkMode, Context): s.Signature =
import TypeOps._
val sig = sym.info.toSemanticSig(sym)
println("")
println(sym.toString)
println(s"=========sym.info================")
pprint.pprintln(sym.info)
val sig = sym.info.toSemanticSig(sym)
println(s"=========sig================")
pprint.pprintln(sig)
sig
Expand All @@ -32,7 +33,9 @@ object TypeOps:
def loop(tpe: Type): s.Signature = tpe match {
case mt: MethodType =>
val stparams = Some(s.Scope())
val sparamss = sym.rawParamss.map(_.sscope)
val paramss =
if (sym.rawParamss.nonEmpty) sym.rawParamss else sym.paramSymss
val sparamss = paramss.map(_.sscope)
s.MethodSignature(
stparams,
sparamss,
Expand All @@ -46,7 +49,7 @@ object TypeOps:
else None
val sparents = cls.parents.map(_.toSemanticType(sym))
val sself = cls.selfType.toSemanticType(sym)
val decls = cls.decls.toList.sscope(using LinkMode.HardlinkChildren)
val decls = cls.decls.toList.sscope
s.ClassSignature(stparams, sparents, sself, Some(decls))

case TypeBounds(lo, hi) =>
Expand All @@ -61,11 +64,15 @@ object TypeOps:
case pt: PolyType =>
loop(pt.resType) match {
case m: s.MethodSignature =>
val tparamss = sym.rawParamss.filter(ps => ps.forall(_.isTypeParam))
val paramss =
if (sym.rawParamss.nonEmpty) sym.rawParamss else sym.paramSymss
val tparamss = paramss.filter(ps => ps.forall(_.isTypeParam))
val stparams = tparamss.flatten.sscope
m.copy(typeParameters = Some(stparams))
case v: s.ValueSignature =>
val tparamss = sym.rawParamss.filter(ps => ps.forall(_.isTypeParam))
val paramss =
if (sym.rawParamss.nonEmpty) sym.rawParamss else sym.paramSymss
val tparamss = paramss.filter(ps => ps.forall(_.isTypeParam))
val stparams = tparamss.flatten.sscope
s.ValueSignature(s.UniversalType(Some(stparams), v.tpe))
case _ => s.Signature.Empty
Expand Down Expand Up @@ -130,7 +137,6 @@ object TypeOps:

case rt @ RefinedType(parent, name, info) =>
// `X { def x: Int; def y: Int }`
//
// RefinedType(
// parent = RefinedType(
// parent = TypeRef(..., X)
Expand All @@ -139,39 +145,32 @@ object TypeOps:
// refinedName = x
// refinedInfo = TypeRef(..., Int)
// )

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 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)))
// flatten parent types to list
// e.g. `X with Y with Z { refined }`
// RefinedType(parent = AndType(X, AndType(Y, Z)), ...)
// => List(X, Y, Z)
def flattenParent(parent: Type): List[s.Type] = parent match {
case AndType(tp1, tp2) =>
flattenParent(tp1) ++ flattenParent(tp2)
case _ => List(loop(parent))
}
val decls = for {

val (parent, refinedInfos) = flatten(rt, List.empty)
val stpe = s.WithType(flattenParent(parent))

// Create dummy symbols for refinements
// since there's no way to retrieve symbols of refinements from RefinedType at this moment.
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
}
yield newSymbol(sym, name, EmptyFlags, info)
val sdecls = decls.sscope(using LinkMode.HardlinkChildren)
s.StructuralType(stpe, Some(sdecls))

Expand Down

0 comments on commit a46e4c7

Please sign in to comment.