@@ -33,7 +33,8 @@ import collection.mutable
33
33
* stack frames for inlined calls.
34
34
**/
35
35
object InlinedSourceMaps :
36
- private case class Request (targetPos : SourcePosition , origPos : SourcePosition , firstFakeLine : Int )
36
+ // private case class Request(targetPos: SourcePosition, origPos: SourcePosition, firstFakeLine: Int)
37
+ private case class Request (inline : Inlined , firstFakeLine : Int )
37
38
38
39
private class File (id : Int , name : String , path : Option [String ]):
39
40
def write (b : mutable.StringBuilder ): Unit =
@@ -81,37 +82,29 @@ object InlinedSourceMaps:
81
82
b ++= " *E\n "
82
83
end Stratum
83
84
84
- // targetPos is the position of the inlined call inlined(5)
85
- // origPos is the position of the inlined code inline def inlined(arg) { ... }
86
85
def sourceMapFor (cunit : CompilationUnit )(internalNameProvider : Symbol => String )(using Context ): InlinedSourceMap =
87
- val requests = mutable.ListBuffer .empty[( SourcePosition , SourcePosition ) ]
86
+ val requests = mutable.ListBuffer .empty[Inlined ]
88
87
var internalNames = Map .empty[SourceFile , String ]
89
88
90
89
class RequestCollector (enclosingFile : SourceFile ) extends TreeTraverser :
91
90
override def traverse (tree : Tree )(using Context ): Unit =
92
- if tree.hasAttachment(InliningPosition ) then
93
- tree.getAttachment(InliningPosition ) match
94
- case Some (InliningPosition (l)) =>
95
- l.foreach {
96
- (targetPos, cls) =>
97
- if tree.source != enclosingFile && tree.source != cunit.source then
98
- requests += (targetPos -> tree.sourcePos)
99
-
100
- cls match
101
- case Some (symbol) if ! internalNames.isDefinedAt(tree.source) =>
102
- internalNames += (tree.source -> internalNameProvider(symbol))
103
- // We are skipping any internal name info if we already have one stored in our map
104
- // because a debugger will use internal name only to localize matching source.
105
- // Both old and new internal names are associated with the same source file
106
- // so it doesn't matter if internal name is not matching used symbol.
107
- case _ => ()
108
- }
109
- traverseChildren(tree)
110
- case None =>
111
- // Not exactly sure in which cases it is happening. Should we report warning?
112
- traverseChildren(tree)
113
- else
114
- traverseChildren(tree)
91
+ tree match
92
+ case Inlined (call, bindings, expansion) =>
93
+ if expansion.source != enclosingFile && expansion.source != cunit.source then
94
+ requests += tree.asInstanceOf [Inlined ]
95
+ val topLevelClass = Option .when(! call.isEmpty)(call.symbol.topLevelClass)
96
+
97
+ topLevelClass match
98
+ case Some (symbol) if ! internalNames.isDefinedAt(tree.source) =>
99
+ internalNames += (tree.source -> internalNameProvider(symbol))
100
+ // We are skipping any internal name info if we already have one stored in our map
101
+ // because a debugger will use internal name only to localize matching source.
102
+ // Both old and new internal names are associated with the same source file
103
+ // so it doesn't matter if internal name is not matching used symbol.
104
+ case _ => ()
105
+
106
+ traverseChildren(tree)
107
+ case _ => traverseChildren(tree)
115
108
end RequestCollector
116
109
117
110
// Don't generate mappings for the quotes compiled at runtime by the staging compiler
@@ -126,7 +119,7 @@ object InlinedSourceMaps:
126
119
127
120
RequestCollector (cunit.source).traverse(cunit.tpdTree)
128
121
129
- val allocated = requests.map(r => Request (r._1, r._2, allocate(r._2 )))
122
+ val allocated = requests.map(r => Request (r, allocate(r.expansion.sourcePos )))
130
123
131
124
InlinedSourceMap (cunit, allocated.toList, internalNames)
132
125
end sourceMapFor
@@ -136,53 +129,25 @@ object InlinedSourceMaps:
136
129
requests : List [Request ],
137
130
internalNames : Map [SourceFile , String ])(using Context ):
138
131
139
- def debugExtension : Option [String ] = Option .when(requests.nonEmpty) {
140
- val scalaStratum =
141
- val files = cunit.source :: requests.map(_.origPos.source).distinct.filter(_ != cunit.source)
142
- val mappings = requests.map { case Request (_, origPos, firstFakeLine) =>
143
- Mapping (origPos.startLine, files.indexOf(origPos.source) + 1 , origPos.lines.length, firstFakeLine, 1 )
144
- }
145
- Stratum (" Scala" ,
146
- files.zipWithIndex.map { case (f, n) => File (n + 1 , f.name, internalNames.get(f)) },
147
- Mapping (0 , 1 , cunit.tpdTree.sourcePos.lines.length, 0 , 1 ) +: mappings
148
- )
149
-
150
- val debugStratum =
151
- val mappings = requests.map { case Request (targetPos, origPos, firstFakeLine) =>
152
- Mapping (targetPos.startLine, 1 , 1 , firstFakeLine, origPos.lines.length)
153
- }
154
- Stratum (" ScalaDebug" , File (1 , cunit.source.name, None ) :: Nil , mappings)
155
-
156
- val b = new StringBuilder
157
- b ++= " SMAP\n "
158
- b ++= cunit.source.name
159
- b += '\n '
160
- b ++= " Scala\n "
161
- scalaStratum.write(b)
162
- debugStratum.write(b)
163
- b.toString
164
- }
165
-
166
- var lastNestedInlineLine = - 1
167
-
168
- def lineFor (sourcePos : SourcePosition , lastRealNr : Int , attachement : Option [InliningPosition ]): Option [Int ] =
169
-
170
- if attachement.isDefined then
171
- attachement.get.targetPos.find(p => p._1.source == sourcePos.source) match
172
- case Some ((pos, _)) =>
173
- lastNestedInlineLine = pos.startLine
174
- case None => ()
175
-
176
- requests.find(r =>
177
- r.origPos.contains(sourcePos) &&
178
- (if r.targetPos.source == cunit.source then r.targetPos.endLine + 1 >= lastRealNr
179
- else r.targetPos.startLine >= lastNestedInlineLine
180
- )
181
- ) match
182
- case Some (request) =>
183
- val offset = sourcePos.startLine - request.origPos.startLine
184
- val virtualLine = request.firstFakeLine + offset
185
- Some (virtualLine + 1 ) // + 1 because the first line is 1 in the LineNumberTable
186
- case None =>
187
- // report.warning(s"${sourcePos.show} was inlined in ${cunit.source} but its inlining position was not recorded.")
188
- None
132
+ def debugExtension : Option [String ] = Some (" TODO" )
133
+
134
+ private val inlines = mutable.ListBuffer .empty[Inlined ]
135
+
136
+ def lineFor (tree : Tree ): Option [Int ] =
137
+
138
+ tree match
139
+ case Inlined (call, binding, expansion) =>
140
+ inlines += tree.asInstanceOf [Inlined ]
141
+ None
142
+ case _ =>
143
+ val sourcePos = tree.sourcePos
144
+ val inline = inlines.findLast(_.expansion.contains(tree))
145
+ requests.findLast(r => r.inline .expansion.contains(tree)) match
146
+ case Some (request) =>
147
+ val offset = sourcePos.startLine - request.inline.expansion.sourcePos.startLine
148
+ val virtualLine = request.firstFakeLine + offset
149
+ if requests.filter(_.inline.expansion.contains(tree)).size > 1 then None
150
+ else Some (virtualLine + 1 ) // + 1 because the first line is 1 in the LineNumberTable
151
+ case None =>
152
+ // report.warning(s"${sourcePos.show} was inlined in ${cunit.source} but its inlining position was not recorded.")
153
+ None
0 commit comments