Skip to content

Commit f0aa7a9

Browse files
committed
modify spans of statements with end markers
1 parent 65187a3 commit f0aa7a9

File tree

4 files changed

+42
-31
lines changed

4 files changed

+42
-31
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ object desugar {
182182
tpt = TypeTree(defn.UnitType),
183183
rhs = setterRhs
184184
).withMods((mods | Accessor) &~ (CaseAccessor | GivenOrImplicit | Lazy))
185-
.dropEndIndex() // the end marker should only appear on the getter definition
185+
.dropEndMarker() // the end marker should only appear on the getter definition
186186
Thicket(vdef1, setter)
187187
}
188188
else vdef1
@@ -875,7 +875,6 @@ object desugar {
875875
val modul = ValDef(moduleName, clsRef, New(clsRef, Nil))
876876
.withMods(mods.toTermFlags & RetainedModuleValFlags | ModuleValCreationFlags)
877877
.withSpan(mdef.span.startPos)
878-
.withEndIndex(copyFrom = mdef) // copy over the end marker position to the module val
879878
val ValDef(selfName, selfTpt, _) = impl.self
880879
val selfMods = impl.self.mods
881880
if (!selfTpt.isEmpty) report.error(ObjectMayNotHaveSelfType(mdef), impl.self.srcPos)
@@ -885,6 +884,7 @@ object desugar {
885884
val clsTmpl = cpy.Template(impl)(self = clsSelf, body = impl.body)
886885
val cls = TypeDef(clsName, clsTmpl)
887886
.withMods(mods.toTypeFlags & RetainedModuleClassFlags | ModuleClassCreationFlags)
887+
.withEndMarker(copyFrom = mdef) // copy over the end marker position to the module class def
888888
Thicket(modul, classDef(cls).withSpan(mdef.span))
889889
}
890890
}

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

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -327,42 +327,51 @@ object Trees {
327327

328328
extension (mdef: untpd.DefTree) def mods: untpd.Modifiers = mdef.rawMods
329329

330-
/** PackageDef | NamedDefTree */
331-
sealed trait WithEndMarker:
332-
self: Attachment.Container =>
330+
sealed trait WithEndMarker[-T >: Untyped]:
331+
self: PackageDef[T] | NamedDefTree[T] =>
333332

334333
import WithEndMarker.*
335334

336335
final def endSpan(using Context): Span =
337-
self.getAttachment(EndIndex) match
338-
case Some(end) =>
339-
val realName = srcName.stripModuleClassSuffix.lastPart
340-
Span(end - realName.length, end)
341-
case none => NoSpan
336+
if hasEndMarker then
337+
val realName = srcName.stripModuleClassSuffix.lastPart
338+
span.withStart(span.end - realName.length)
339+
else
340+
NoSpan
342341

342+
/** The name in source code that represents this construct,
343+
* and is the name that the user must write to create a valid
344+
* end marker.
345+
* e.g. a constructor definition is terminated in the source
346+
* code by `end this`, so it's `srcName` should return `this`.
347+
*/
343348
protected def srcName(using Context): Name
344349

345-
final def withEndIndex(index: Int): self.type =
346-
self.withAttachment(EndIndex, index)
350+
final def withEndMarker(): self.type =
351+
self.withAttachment(HasEndMarker, ())
347352

348-
final def withEndIndex(copyFrom: WithEndMarker): self.type =
349-
copyFrom.endIndex.foreach(withEndIndex)
350-
this
353+
final def withEndMarker(copyFrom: WithEndMarker[?]): self.type =
354+
if copyFrom.hasEndMarker then
355+
this.withEndMarker()
356+
else
357+
this
351358

352-
final def dropEndIndex(): self.type =
353-
self.removeAttachment(EndIndex)
359+
final def dropEndMarker(): self.type =
360+
self.removeAttachment(HasEndMarker)
354361
this
355362

356-
protected def endIndex: Option[Int] = self.getAttachment(EndIndex)
363+
protected def hasEndMarker: Boolean = self.hasAttachment(HasEndMarker)
357364

358365
object WithEndMarker:
359-
/** Property key for trees with an `end` marker */
360-
private val EndIndex: Property.StickyKey[Int] = Property.StickyKey()
366+
/** Property key that signals the tree was terminated
367+
* with an `end` marker in the source code
368+
*/
369+
private val HasEndMarker: Property.StickyKey[Unit] = Property.StickyKey()
361370

362371
end WithEndMarker
363372

364373
abstract class NamedDefTree[-T >: Untyped](implicit @constructorOnly src: SourceFile)
365-
extends NameTree[T] with DefTree[T] with WithEndMarker {
374+
extends NameTree[T] with DefTree[T] with WithEndMarker[T] {
366375
type ThisTree[-T >: Untyped] <: NamedDefTree[T]
367376

368377
protected def srcName(using Context): Name =
@@ -897,7 +906,7 @@ object Trees {
897906

898907
/** package pid { stats } */
899908
case class PackageDef[-T >: Untyped] private[ast] (pid: RefTree[T], stats: List[Tree[T]])(implicit @constructorOnly src: SourceFile)
900-
extends ProxyTree[T] with WithEndMarker {
909+
extends ProxyTree[T] with WithEndMarker[T] {
901910
type ThisTree[-T >: Untyped] = PackageDef[T]
902911
def forwardTo: RefTree[T] = pid
903912
protected def srcName(using Context): Name = pid.name

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,7 +1275,13 @@ object Parsers {
12751275

12761276
def checkEndMarker[T <: Tree](stats: ListBuffer[T]): Unit =
12771277

1278-
def matches(stat: Tree): Boolean = stat match
1278+
def updateSpanOfLast(last: T): Unit =
1279+
last match
1280+
case last: WithEndMarker[t] => last.withEndMarker()
1281+
case _ =>
1282+
last.span = last.span.withEnd(in.lastCharOffset)
1283+
1284+
def matches(stat: T): Boolean = stat match
12791285
case stat: MemberDef if !stat.name.isEmpty =>
12801286
if stat.name == nme.CONSTRUCTOR then in.token == THIS
12811287
else in.isIdent && in.name == stat.name.toTermName
@@ -1293,14 +1299,10 @@ object Parsers {
12931299
case _: (ForYield | ForDo) => in.token == FOR
12941300
case _ => false
12951301

1296-
def matchesAndSetEnd(stat: Tree): Boolean = {
1297-
val didMatch = matches(stat)
1302+
def matchesAndSetEnd(last: T): Boolean = {
1303+
val didMatch = matches(last)
12981304
if didMatch then
1299-
stat match
1300-
case stat: WithEndMarker =>
1301-
stat.withEndIndex(index = in.lastCharOffset)
1302-
case _ =>
1303-
()
1305+
updateSpanOfLast(last)
13041306
didMatch
13051307
}
13061308

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ class ExtractSemanticDB extends Phase:
240240
traverseChildren(tree)
241241

242242
tree match
243-
case tree: WithEndMarker =>
243+
case tree: WithEndMarker[t] =>
244244
val endSpan = tree.endSpan
245245
if endSpan.exists then
246246
registerUseGuarded(None, tree.symbol, endSpan, tree.source)

0 commit comments

Comments
 (0)