Skip to content

Commit a46e4c7

Browse files
committed
Generate dummy symbols for refinements
1 parent ebdf900 commit a46e4c7

File tree

2 files changed

+36
-33
lines changed

2 files changed

+36
-33
lines changed

compiler/src/dotty/tools/dotc/semanticdb/SemanticSymbolBuilder.scala

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,18 +93,22 @@ object SemanticSymbolBuilder:
9393
*/
9494
def localIdx(sym: Symbol)(using Context): Int =
9595
val startPos =
96-
assert(sym.span.exists, s"$sym should have a span")
97-
sym.span.start
96+
if sym.span.exists then Some(sym.span.start) else None
97+
// assert(sym.span.exists, s"$sym should have a span")
9898
@tailrec
9999
def computeLocalIdx(sym: Symbol): Int = locals get sym match
100100
case Some(idx) => idx
101-
case None => symsAtOffset(startPos).find(_.name == sym.name) match
101+
case None => (for {
102+
pos <- startPos
103+
samePosSyms <- symsAtOffset.get(pos)
104+
sameName <- samePosSyms.find(_.name == sym.name)
105+
} yield sameName) match
102106
case Some(other) => computeLocalIdx(other)
103107
case None =>
104108
val idx = nextLocalIdx
105109
nextLocalIdx += 1
106110
locals(sym) = idx
107-
symsAtOffset(startPos) += sym
111+
startPos.foreach(pos => symsAtOffset(pos) += sym)
108112
idx
109113
end computeLocalIdx
110114
computeLocalIdx(sym)

compiler/src/dotty/tools/dotc/semanticdb/SymbolOps.scala

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import core.Symbols._
66
import core.Contexts.Context
77
import core.Types._
88
import core.Annotations.Annotation
9+
import core.Flags.EmptyFlags
910
import ast.tpd._
1011

1112
import dotty.tools.dotc.{semanticdb => s}
@@ -16,11 +17,11 @@ object SymbolOps:
1617
extension (sym: Symbol)
1718
def sig(using LinkMode, Context): s.Signature =
1819
import TypeOps._
20+
val sig = sym.info.toSemanticSig(sym)
1921
println("")
2022
println(sym.toString)
2123
println(s"=========sym.info================")
2224
pprint.pprintln(sym.info)
23-
val sig = sym.info.toSemanticSig(sym)
2425
println(s"=========sig================")
2526
pprint.pprintln(sig)
2627
sig
@@ -32,7 +33,9 @@ object TypeOps:
3233
def loop(tpe: Type): s.Signature = tpe match {
3334
case mt: MethodType =>
3435
val stparams = Some(s.Scope())
35-
val sparamss = sym.rawParamss.map(_.sscope)
36+
val paramss =
37+
if (sym.rawParamss.nonEmpty) sym.rawParamss else sym.paramSymss
38+
val sparamss = paramss.map(_.sscope)
3639
s.MethodSignature(
3740
stparams,
3841
sparamss,
@@ -46,7 +49,7 @@ object TypeOps:
4649
else None
4750
val sparents = cls.parents.map(_.toSemanticType(sym))
4851
val sself = cls.selfType.toSemanticType(sym)
49-
val decls = cls.decls.toList.sscope(using LinkMode.HardlinkChildren)
52+
val decls = cls.decls.toList.sscope
5053
s.ClassSignature(stparams, sparents, sself, Some(decls))
5154

5255
case TypeBounds(lo, hi) =>
@@ -61,11 +64,15 @@ object TypeOps:
6164
case pt: PolyType =>
6265
loop(pt.resType) match {
6366
case m: s.MethodSignature =>
64-
val tparamss = sym.rawParamss.filter(ps => ps.forall(_.isTypeParam))
67+
val paramss =
68+
if (sym.rawParamss.nonEmpty) sym.rawParamss else sym.paramSymss
69+
val tparamss = paramss.filter(ps => ps.forall(_.isTypeParam))
6570
val stparams = tparamss.flatten.sscope
6671
m.copy(typeParameters = Some(stparams))
6772
case v: s.ValueSignature =>
68-
val tparamss = sym.rawParamss.filter(ps => ps.forall(_.isTypeParam))
73+
val paramss =
74+
if (sym.rawParamss.nonEmpty) sym.rawParamss else sym.paramSymss
75+
val tparamss = paramss.filter(ps => ps.forall(_.isTypeParam))
6976
val stparams = tparamss.flatten.sscope
7077
s.ValueSignature(s.UniversalType(Some(stparams), v.tpe))
7178
case _ => s.Signature.Empty
@@ -130,7 +137,6 @@ object TypeOps:
130137

131138
case rt @ RefinedType(parent, name, info) =>
132139
// `X { def x: Int; def y: Int }`
133-
//
134140
// RefinedType(
135141
// parent = RefinedType(
136142
// parent = TypeRef(..., X)
@@ -139,39 +145,32 @@ object TypeOps:
139145
// refinedName = x
140146
// refinedInfo = TypeRef(..., Int)
141147
// )
142-
143148
type RefinedInfo = (core.Names.Name, Type)
144149
def flatten(tpe: Type, acc: List[RefinedInfo]): (Type, List[RefinedInfo]) = tpe match {
145150
case RefinedType(parent, name, info) =>
146151
flatten(parent, acc :+ (name, info))
147152
case _ =>
148153
(tpe, acc)
149154
}
150-
val (parent, refinedInfos) = flatten(rt, List.empty)
151155

152-
val stpe = parent match {
153-
// val tp: M with N { def k: Int } = ???
154-
case AndType(x, y) =>
155-
s.WithType(Seq(loop(x), loop(y))) // TODO: for M with N with L
156-
case _ =>
157-
s.WithType(Seq(loop(parent)))
156+
// flatten parent types to list
157+
// e.g. `X with Y with Z { refined }`
158+
// RefinedType(parent = AndType(X, AndType(Y, Z)), ...)
159+
// => List(X, Y, Z)
160+
def flattenParent(parent: Type): List[s.Type] = parent match {
161+
case AndType(tp1, tp2) =>
162+
flattenParent(tp1) ++ flattenParent(tp2)
163+
case _ => List(loop(parent))
158164
}
159-
val decls = for {
165+
166+
val (parent, refinedInfos) = flatten(rt, List.empty)
167+
val stpe = s.WithType(flattenParent(parent))
168+
169+
// Create dummy symbols for refinements
170+
// since there's no way to retrieve symbols of refinements from RefinedType at this moment.
171+
val decls = for
160172
(name, info) <- refinedInfos
161-
} yield {
162-
// do we need this?
163-
// isLegalPrefix returns true outside in typer
164-
val pre = ctx.typeAssigner.maybeSkolemizePrefix(rt, name)
165-
val denot = rt.findMember(name, pre)
166-
// assert(denot.info eq info, s"(${denot.info.show}) is not eq to (${info.show})")
167-
println(s"denot.info: ${denot.info}, info: ${info}, sym: ${denot.symbol}")
168-
val sym =
169-
if denot.symbol.exists then
170-
println(s"refined ${denot.symbol.show} with ${info.show}")
171-
denot.symbol
172-
else ???
173-
sym
174-
}
173+
yield newSymbol(sym, name, EmptyFlags, info)
175174
val sdecls = decls.sscope(using LinkMode.HardlinkChildren)
176175
s.StructuralType(stpe, Some(sdecls))
177176

0 commit comments

Comments
 (0)