Skip to content

Commit 7f305d5

Browse files
committed
Add path to allow setting sources togethet with spans in Positioned
1 parent 2671fe3 commit 7f305d5

File tree

3 files changed

+34
-20
lines changed

3 files changed

+34
-20
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1379,7 +1379,7 @@ object desugar {
13791379
mayNeedSetter
13801380
}
13811381

1382-
private def derivedDefDef(original: Tree, named: NameTree, tpt: Tree, rhs: Tree, mods: Modifiers)(implicit src: SourceFile) =
1382+
private def derivedDefDef(original: Tree, named: NameTree, tpt: Tree, rhs: Tree, mods: Modifiers)(using Context) =
13831383
DefDef(named.name.asTermName, Nil, Nil, tpt, rhs)
13841384
.withMods(mods)
13851385
.withSpan(original.span.withPoint(named.span.start))

compiler/src/dotty/tools/dotc/ast/Positioned.scala

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,32 +46,41 @@ abstract class Positioned(implicit @constructorOnly src: SourceFile) extends Src
4646
uniqueId = src.nextId
4747
span = envelope(src)
4848

49-
val source: SourceFile = src
49+
private var mySource: SourceFile = src
50+
51+
def source: SourceFile = mySource
52+
def source_=(x: SourceFile): Unit = { mySource = x }
53+
5054
def sourcePos(using Context): SourcePosition = source.atSpan(span)
5155

5256
/** This positioned item, widened to `SrcPos`. Used to make clear we only need the
5357
* position, typically for error reporting.
5458
*/
5559
final def srcPos: SrcPos = this
5660

61+
def withSpanAndSource(span: Span, src: SourceFile): this.type =
62+
if mySpan == span && (source eq src) then this
63+
else
64+
val newpd: this.type =
65+
if mySpan.isSynthetic then
66+
if !mySpan.exists && span.exists then
67+
envelope(src, span.startPos) // fill in children spans
68+
this
69+
else cloned
70+
newpd.span = span
71+
newpd.source = src
72+
newpd
73+
5774
/** A positioned item like this one with given `span`.
5875
* If the positioned item is source-derived, a clone is returned.
5976
* If the positioned item is synthetic, the position is updated
6077
* destructively and the item itself is returned.
6178
*/
62-
def withSpan(span: Span): this.type =
63-
if (span == mySpan) this
64-
else {
65-
val newpd: this.type =
66-
if (mySpan.isSynthetic) {
67-
if (!mySpan.exists && span.exists)
68-
envelope(source, span.startPos) // fill in children spans
69-
this
70-
}
71-
else cloneIn(source)
72-
newpd.span = span
73-
newpd
74-
}
79+
def withSpan(span: Span)(using Context): this.type =
80+
withSpanAndSource(span, source)
81+
82+
def withSourcePos(pos: SourcePosition): this.type =
83+
withSpanAndSource(pos.span, pos.source)
7584

7685
/** The union of startSpan and the spans of all positioned children that
7786
* have the same source as this node, except that Inlined nodes only
@@ -130,6 +139,11 @@ abstract class Positioned(implicit @constructorOnly src: SourceFile) extends Src
130139
newpd
131140
}
132141

142+
def cloned: this.type =
143+
val newpd: this.type = clone.asInstanceOf[this.type]
144+
newpd.uniqueId = source.nextId
145+
newpd
146+
133147
def contains(that: Positioned): Boolean = {
134148
def isParent(x: Any): Boolean = x match {
135149
case x: Positioned =>

compiler/src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -853,21 +853,21 @@ object Trees {
853853
case nil => s
854854
combine(NoSpan, trees)
855855

856-
override def withSpan(span: Span): this.type =
856+
override def withSpan(span: Span)(using Context): this.type =
857857
mapElems(_.withSpan(span)).asInstanceOf[this.type]
858858
}
859859

860860
class EmptyTree[T >: Untyped] extends Thicket(Nil)(NoSource) {
861861
// assert(uniqueId != 1492)
862-
override def withSpan(span: Span) = throw AssertionError("Cannot change span of EmptyTree")
862+
override def withSpan(span: Span)(using Context) = throw AssertionError("Cannot change span of EmptyTree")
863863
}
864864

865865
class EmptyValDef[T >: Untyped] extends ValDef[T](
866866
nme.WILDCARD, genericEmptyTree[T], genericEmptyTree[T])(NoSource) with WithoutTypeOrPos[T] {
867867
myTpe = NoType.asInstanceOf[T]
868868
setMods(untpd.Modifiers(PrivateLocal))
869869
override def isEmpty: Boolean = true
870-
override def withSpan(span: Span) = throw AssertionError("Cannot change span of EmptyValDef")
870+
override def withSpan(span: Span)(using Context) = throw AssertionError("Cannot change span of EmptyValDef")
871871
}
872872

873873
@sharable val theEmptyTree = new EmptyTree[Type]()
@@ -1028,11 +1028,11 @@ object Trees {
10281028

10291029
protected def finalize(tree: Tree, copied: untpd.Tree): copied.ThisTree[T] =
10301030
Stats.record(s"TreeCopier.finalize/${tree.getClass == copied.getClass}")
1031-
postProcess(tree, copied.withSpan(tree.span).withAttachmentsFrom(tree))
1031+
postProcess(tree, copied.withSpanAndSource(tree.span, copied.source).withAttachmentsFrom(tree))
10321032

10331033
protected def finalize(tree: Tree, copied: untpd.MemberDef): copied.ThisTree[T] =
10341034
Stats.record(s"TreeCopier.finalize/${tree.getClass == copied.getClass}")
1035-
postProcess(tree, copied.withSpan(tree.span).withAttachmentsFrom(tree))
1035+
postProcess(tree, copied.withSpanAndSource(tree.span, copied.source).withAttachmentsFrom(tree))
10361036

10371037
def Ident(tree: Tree)(name: Name)(using Context): Ident = tree match {
10381038
case tree: Ident if name == tree.name => tree

0 commit comments

Comments
 (0)