Skip to content

Commit 2d5e9e1

Browse files
committed
cache line number and position comment parses
1 parent 4ab6e58 commit 2d5e9e1

File tree

2 files changed

+46
-20
lines changed

2 files changed

+46
-20
lines changed

sourcecode/src-2/sourcecode/Macros.scala

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package sourcecode
22

3+
import java.util.concurrent.ConcurrentHashMap
34
import language.experimental.macros
45

56
trait NameMacros {
@@ -95,36 +96,47 @@ object Macros {
9596
}
9697

9798
private val filePrefix = "//SOURCECODE_ORIGINAL_FILE_PATH="
99+
private val filePrefixCache =
100+
new ConcurrentHashMap[scala.reflect.internal.util.SourceFile, Option[String]]()
98101
private def findOriginalFile(chars: Array[Char]): Option[String] = {
99102
new String(chars).linesIterator.find(_.contains(filePrefix)).map(_.split(filePrefix).last)
100103
}
101104

102105
def fileImpl(c: Compat.Context): c.Expr[sourcecode.File] = {
103106
import c.universe._
104107

105-
val file = findOriginalFile(c.enclosingPosition.source.content)
108+
val file = filePrefixCache
109+
.computeIfAbsent(c.enclosingPosition.source, source => findOriginalFile(source.content))
106110
.getOrElse(c.enclosingPosition.source.path)
107111

108112
c.Expr[sourcecode.File](q"""${c.prefix}($file)""")
109113
}
110114

111115
def fileNameImpl(c: Compat.Context): c.Expr[sourcecode.FileName] = {
112116
import c.universe._
113-
val fileName = findOriginalFile(c.enclosingPosition.source.content)
117+
val fileName = filePrefixCache
118+
.computeIfAbsent(c.enclosingPosition.source, source => findOriginalFile(source.content))
114119
.getOrElse(c.enclosingPosition.source.path)
115120
.split('/').last
116121
c.Expr[sourcecode.FileName](q"""${c.prefix}($fileName)""")
117122
}
118123

119124
private val linePrefix = "//SOURCECODE_ORIGINAL_CODE_START_MARKER"
125+
private val linePrefixCache =
126+
new ConcurrentHashMap[scala.reflect.internal.util.SourceFile, Int]()
127+
120128
def lineImpl(c: Compat.Context): c.Expr[sourcecode.Line] = {
121129
import c.universe._
122-
val offset = new String(c.enclosingPosition.source.content)
123-
.linesIterator
124-
.indexWhere(_.contains(linePrefix)) match{
125-
case -1 => 0
126-
case n => n
127-
}
130+
val offset = linePrefixCache.computeIfAbsent(
131+
c.enclosingPosition.source,
132+
source => new String(source.content)
133+
.linesIterator
134+
.indexWhere(_.contains(linePrefix)) match{
135+
case -1 => 0
136+
case n => n
137+
}
138+
)
139+
128140
val line = c.enclosingPosition.line - offset
129141
c.Expr[sourcecode.Line](q"""${c.prefix}($line)""")
130142
}

sourcecode/src-3/sourcecode/Macros.scala

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package sourcecode
22

3+
import java.util.concurrent.ConcurrentHashMap
34
import scala.language.implicitConversions
4-
import scala.quoted._
5+
import scala.quoted.*
56

67
trait NameMacros {
78
inline implicit def generate: Name =
@@ -157,35 +158,48 @@ object Macros {
157158
}
158159

159160
private val filePrefix = "//SOURCECODE_ORIGINAL_FILE_PATH="
160-
161+
private val filePrefixCache =
162+
new ConcurrentHashMap[Any, Option[String]]()
161163
private def findOriginalFile(chars: Array[Char]): Option[String] = {
162164
new String(chars).linesIterator.find(_.contains(filePrefix)).map(_.split(filePrefix).last)
163165
}
164166
def fileImpl(using Quotes): Expr[sourcecode.File] = {
165167
import quotes.reflect._
166-
val file = quotes.reflect.Position.ofMacroExpansion.sourceFile.content
168+
val file = filePrefixCache.computeIfAbsent(
169+
quotes.reflect.Position.ofMacroExpansion.sourceFile,
170+
_ => quotes.reflect.Position.ofMacroExpansion.sourceFile.content
167171
.flatMap(s => findOriginalFile(s.toCharArray))
172+
)
168173
.getOrElse(quotes.reflect.Position.ofMacroExpansion.sourceFile.path)
169174
'{new sourcecode.File(${Expr(file)})}
170175
}
171176

172177
def fileNameImpl(using Quotes): Expr[sourcecode.FileName] = {
173-
val name = quotes.reflect.Position.ofMacroExpansion.sourceFile.content
174-
.flatMap(s => findOriginalFile(s.toCharArray).map(_.split('/').last))
178+
val name = filePrefixCache.computeIfAbsent(
179+
quotes.reflect.Position.ofMacroExpansion.sourceFile,
180+
_ => quotes.reflect.Position.ofMacroExpansion.sourceFile.content
181+
.flatMap(s => findOriginalFile(s.toCharArray).map(_.split('/').last)
182+
).flatMap(s => findOriginalFile(s.toCharArray)))
175183
.getOrElse(quotes.reflect.Position.ofMacroExpansion.sourceFile.name)
176184

177185
'{new sourcecode.FileName(${Expr(name)})}
178186
}
179187

180188
private val linePrefix = "//SOURCECODE_ORIGINAL_CODE_START_MARKER"
189+
private val linePrefixCache =
190+
new ConcurrentHashMap[Any, Int]()
181191
def lineImpl(using Quotes): Expr[sourcecode.Line] = {
182-
val offset = quotes.reflect.Position.ofMacroExpansion.sourceFile.content
183-
.iterator
184-
.flatMap(_.linesIterator)
185-
.indexWhere(_.contains(linePrefix)) match{
186-
case -1 => 0
187-
case n => n
188-
}
192+
val offset = linePrefixCache.computeIfAbsent(
193+
quotes.reflect.Position.ofMacroExpansion.sourceFile,
194+
_ =>
195+
quotes.reflect.Position.ofMacroExpansion.sourceFile.content
196+
.iterator
197+
.flatMap(_.linesIterator)
198+
.indexWhere(_.contains(linePrefix)) match{
199+
case -1 => 0
200+
case n => n
201+
}
202+
)
189203
val line = quotes.reflect.Position.ofMacroExpansion.startLine + 1 - offset
190204
'{new sourcecode.Line(${Expr(line)})}
191205
}

0 commit comments

Comments
 (0)