@@ -11,14 +11,44 @@ import scala.collection.mutable
11
11
class SyntheticsExtractor :
12
12
import Scala3 .{_ , given }
13
13
14
+ val visited = collection.mutable.HashSet [Tree ]()
15
+
14
16
def tryFindSynthetic (tree : Tree )(using Context , SemanticSymbolBuilder , TypeOps ): Option [s.Synthetic ] =
15
17
extension (synth : s.Synthetic )
16
18
def toOpt : Some [s.Synthetic ] = Some (synth)
17
19
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
19
27
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
+
22
52
case tree : Apply
23
53
if tree.args.nonEmpty &&
24
54
tree.args.forall(arg =>
@@ -46,7 +76,6 @@ class SyntheticsExtractor:
46
76
).toOpt
47
77
48
78
case _ => None
49
- else None
50
79
51
80
private given TreeOps : AnyRef with
52
81
extension (tree : Tree )
@@ -95,4 +124,15 @@ class SyntheticsExtractor:
95
124
case select : Select => isForComprehensionSyntheticName(select)
96
125
case _ => false
97
126
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
+
98
138
end SyntheticsExtractor
0 commit comments