Skip to content

Commit 130c511

Browse files
committed
Support TypeApplication in Synthetic
1 parent d519682 commit 130c511

File tree

3 files changed

+170
-8
lines changed

3 files changed

+170
-8
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,11 @@ class ExtractSemanticDB extends Phase:
245245
registerUseGuarded(None, alt.symbol.companionClass, sel.imported.span, tree.source)
246246
case tree: Inlined =>
247247
traverse(tree.call)
248+
249+
case tree: TypeApply =>
250+
synth.tryFindSynthetic(tree).foreach(synthetics.addOne)
251+
traverseChildren(tree)
252+
248253
case tree: TypeTree =>
249254
tree.typeOpt match
250255
// Any types could be appear inside of `TypeTree`, but

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

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,44 @@ import scala.collection.mutable
1111
class SyntheticsExtractor:
1212
import Scala3.{_, given}
1313

14+
val visited = collection.mutable.HashSet[Tree]()
15+
1416
def tryFindSynthetic(tree: Tree)(using Context, SemanticSymbolBuilder, TypeOps): Option[s.Synthetic] =
1517
extension (synth: s.Synthetic)
1618
def toOpt: Some[s.Synthetic] = Some(synth)
1719

18-
if tree.span.isSynthetic then
20+
val forSynthetic = tree match // not yet supported (for synthetics)
21+
case tree: Apply if isForSynthetic(tree) => true
22+
case tree: TypeApply if isForSynthetic(tree) => true
23+
case _ => false
24+
25+
if visited.contains(tree) || forSynthetic then None
26+
else
1927
tree match
20-
case tree: Apply if isForSynthetic(tree) =>
21-
None // not yet supported (for synthetics)
28+
case tree: TypeApply
29+
if tree.span.isSynthetic &&
30+
tree.args.forall(arg => !arg.symbol.is(Scala2x)) &&
31+
!tree.span.isZeroExtent =>
32+
visited.add(tree)
33+
val fnTree = tree.fun match
34+
// Something like `List.apply[Int](1,2,3)`
35+
case select @ Select(qual, _) if isSyntheticName(select) =>
36+
s.SelectTree(
37+
s.OriginalTree(range(qual.span, tree.source)),
38+
Some(select.toSemanticId)
39+
)
40+
case _ =>
41+
s.OriginalTree(
42+
range(tree.fun.span, tree.source)
43+
)
44+
val targs = tree.args.map(targ => targ.tpe.toSemanticType(targ.symbol)(using LinkMode.SymlinkChildren))
45+
s.Synthetic(
46+
range(tree.span, tree.source),
47+
s.TypeApplyTree(
48+
fnTree, targs
49+
)
50+
).toOpt
51+
2252
case tree: Apply
2353
if tree.args.nonEmpty &&
2454
tree.args.forall(arg =>
@@ -46,7 +76,6 @@ class SyntheticsExtractor:
4676
).toOpt
4777

4878
case _ => None
49-
else None
5079

5180
private given TreeOps: AnyRef with
5281
extension (tree: Tree)
@@ -95,4 +124,15 @@ class SyntheticsExtractor:
95124
case select: Select => isForComprehensionSyntheticName(select)
96125
case _ => false
97126

127+
private def isSyntheticName(select: Select): Boolean =
128+
select.span.toSynthetic == select.qualifier.span.toSynthetic && (
129+
select.name == nme.apply ||
130+
select.name == nme.update ||
131+
select.name == nme.foreach ||
132+
select.name == nme.withFilter ||
133+
select.name == nme.flatMap ||
134+
select.name == nme.map ||
135+
select.name == nme.unapplySeq ||
136+
select.name == nme.unapply)
137+
98138
end SyntheticsExtractor

0 commit comments

Comments
 (0)