@@ -11,14 +11,45 @@ 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 : Apply if isForSynthetic(tree) => None
29
+ case tree : TypeApply
30
+ if tree.span.isSynthetic &&
31
+ tree.args.forall(arg => ! arg.symbol.is(Scala2x )) &&
32
+ ! tree.span.isZeroExtent =>
33
+ visited.add(tree)
34
+ val fnTree = tree.fun match
35
+ // Something like `List.apply[Int](1,2,3)`
36
+ case select @ Select (qual, _) if isSyntheticName(select) =>
37
+ s.SelectTree (
38
+ s.OriginalTree (range(qual.span, tree.source)),
39
+ Some (select.toSemanticId)
40
+ )
41
+ case _ =>
42
+ s.OriginalTree (
43
+ range(tree.fun.span, tree.source)
44
+ )
45
+ val targs = tree.args.map(targ => targ.tpe.toSemanticType(targ.symbol)(using LinkMode .SymlinkChildren ))
46
+ s.Synthetic (
47
+ range(tree.span, tree.source),
48
+ s.TypeApplyTree (
49
+ fnTree, targs
50
+ )
51
+ ).toOpt
52
+
22
53
case tree : Apply
23
54
if tree.args.nonEmpty &&
24
55
tree.args.forall(arg =>
@@ -46,7 +77,6 @@ class SyntheticsExtractor:
46
77
).toOpt
47
78
48
79
case _ => None
49
- else None
50
80
51
81
private given TreeOps : AnyRef with
52
82
extension (tree : Tree )
@@ -95,4 +125,15 @@ class SyntheticsExtractor:
95
125
case select : Select => isForComprehensionSyntheticName(select)
96
126
case _ => false
97
127
128
+ private def isSyntheticName (select : Select ): Boolean =
129
+ select.span.toSynthetic == select.qualifier.span.toSynthetic && (
130
+ select.name == nme.apply ||
131
+ select.name == nme.update ||
132
+ select.name == nme.foreach ||
133
+ select.name == nme.withFilter ||
134
+ select.name == nme.flatMap ||
135
+ select.name == nme.map ||
136
+ select.name == nme.unapplySeq ||
137
+ select.name == nme.unapply)
138
+
98
139
end SyntheticsExtractor
0 commit comments