Skip to content

Commit a688003

Browse files
committed
Reuse relativize logic in semanticDB
1 parent 16c899d commit a688003

File tree

7 files changed

+47
-43
lines changed

7 files changed

+47
-43
lines changed

compiler/src/dotty/tools/dotc/core/tasty/PositionPickler.scala

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,21 @@ import dotty.tools.tasty.TastyBuffer
88
import TastyBuffer._
99

1010
import ast._
11-
import ast.Trees._
12-
import ast.Trees.WithLazyField
11+
import Trees.WithLazyField
1312
import util.{SourceFile, NoSource}
1413
import core._
15-
import Contexts._, Symbols._, Annotations._, Decorators._
14+
import Annotations._, Decorators._
1615
import collection.mutable
1716
import util.Spans._
1817

1918
class PositionPickler(
2019
pickler: TastyPickler,
2120
addrOfTree: PositionPickler.TreeToAddr,
22-
treeAnnots: untpd.MemberDef => List[tpd.Tree])(using Context) {
21+
treeAnnots: untpd.MemberDef => List[tpd.Tree],
22+
relativePathReference: String){
2323

2424
import ast.tpd._
25+
2526
val buf: TastyBuffer = new TastyBuffer(5000)
2627
pickler.newSection(PositionsSection, buf)
2728

@@ -67,9 +68,9 @@ class PositionPickler(
6768
// specialization.
6869
}
6970

70-
def pickleSource(source: SourceFile)(using Context): Unit = {
71+
def pickleSource(source: SourceFile): Unit = {
7172
buf.writeInt(SOURCE)
72-
val relativePath = SourceFile.relativePath(source)
73+
val relativePath = SourceFile.relativePath(source, relativePathReference)
7374
buf.writeInt(pickler.nameBuffer.nameIndex(relativePath.toTermName).index)
7475
}
7576

@@ -94,7 +95,7 @@ class PositionPickler(
9495
case _ => false
9596
}
9697

97-
def traverse(x: Any, current: SourceFile)(using Context): Unit = x match {
98+
def traverse(x: Any, current: SourceFile): Unit = x match {
9899
case x: untpd.Tree =>
99100
if (x.span.exists) {
100101
val addr = addrOfTree(x)

compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ object PickledQuotes {
167167
treePkl.compactify()
168168
if tree.span.exists then
169169
val positionWarnings = new mutable.ListBuffer[String]()
170-
new PositionPickler(pickler, treePkl.buf.addrOfTree, treePkl.treeAnnots)
170+
val reference = ctx.settings.sourceroot.value
171+
new PositionPickler(pickler, treePkl.buf.addrOfTree, treePkl.treeAnnots, reference)
171172
.picklePositions(ctx.compilationUnit.source, tree :: Nil, positionWarnings)
172173
positionWarnings.foreach(report.warning(_))
173174

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

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,23 @@ package semanticdb
55
import core._
66
import Phases._
77
import ast.tpd._
8+
import ast.untpd.given
89
import ast.Trees.mods
910
import Contexts._
1011
import Symbols._
1112
import Flags._
1213
import Names.Name
1314
import StdNames.nme
15+
import NameOps._
1416
import util.Spans.Span
1517
import util.{SourceFile, SourcePosition}
16-
import scala.jdk.CollectionConverters._
17-
import collection.mutable
18-
import java.nio.file.Paths
19-
20-
import dotty.tools.dotc.transform.SymUtils._
21-
22-
import PartialFunction.condOpt
23-
24-
import ast.untpd.given
25-
import NameOps._
18+
import transform.SymUtils._
2619

20+
import scala.jdk.CollectionConverters._
21+
import scala.collection.mutable
2722
import scala.annotation.{ threadUnsafe => tu, tailrec }
23+
import scala.PartialFunction.condOpt
24+
2825

2926
/** Extract symbol references and uses to semanticdb files.
3027
* See https://scalameta.org/docs/semanticdb/specification.html#symbol-1
@@ -590,37 +587,29 @@ object ExtractSemanticDB:
590587
import java.nio.file.Path
591588
import scala.collection.JavaConverters._
592589
import java.nio.file.Files
590+
import java.nio.file.Paths
593591

594592
val name: String = "extractSemanticDB"
595593

596594
def write(source: SourceFile, occurrences: List[SymbolOccurrence], symbolInfos: List[SymbolInformation])(using Context): Unit =
597595
def absolutePath(path: Path): Path = path.toAbsolutePath.normalize
598-
def commonPrefix[T](z: T)(i1: Iterable[T], i2: Iterable[T])(app: (T, T) => T): T =
599-
(i1 lazyZip i2).takeWhile(p => p(0) == p(1)).map(_(0)).foldLeft(z)(app)
600-
val sourcePath = absolutePath(source.file.jpath)
601-
val sourceRoot =
602-
// Here if `sourceRoot` and `sourcePath` do not share a common prefix then `relPath` will not be normalised,
603-
// containing ../.. etc, which is problematic when appending to `/META-INF/semanticdb/` and will not be accepted
604-
// by Files.createDirectories on JDK 11.
605-
val sourceRoot0 = absolutePath(Paths.get(ctx.settings.sourceroot.value))
606-
commonPrefix(sourcePath.getRoot)(sourcePath.asScala, sourceRoot0.asScala)(_ resolve _)
607596
val semanticdbTarget =
608597
val semanticdbTargetSetting = ctx.settings.semanticdbTarget.value
609598
absolutePath(
610599
if semanticdbTargetSetting.isEmpty then ctx.settings.outputDir.value.jpath
611600
else Paths.get(semanticdbTargetSetting)
612601
)
613-
val relPath = sourceRoot.relativize(sourcePath)
602+
val relPath = SourceFile.relativePath(source, ctx.settings.sourceroot.value)
614603
val outpath = semanticdbTarget
615604
.resolve("META-INF")
616605
.resolve("semanticdb")
617606
.resolve(relPath)
618-
.resolveSibling(sourcePath.getFileName().toString() + ".semanticdb")
607+
.resolveSibling(source.name + ".semanticdb")
619608
Files.createDirectories(outpath.getParent())
620609
val doc: TextDocument = TextDocument(
621610
schema = Schema.SEMANTICDB4,
622611
language = Language.SCALA,
623-
uri = Tools.mkURIstring(relPath),
612+
uri = Tools.mkURIstring(Paths.get(relPath)),
624613
text = "",
625614
md5 = internal.MD5.compute(String(source.content)),
626615
symbols = symbolInfos,

compiler/src/dotty/tools/dotc/transform/Pickler.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ class Pickler extends Phase {
7272
Future {
7373
treePkl.compactify()
7474
if tree.span.exists then
75-
new PositionPickler(pickler, treePkl.buf.addrOfTree, treePkl.treeAnnots)
75+
val reference = ctx.settings.sourceroot.value
76+
new PositionPickler(pickler, treePkl.buf.addrOfTree, treePkl.treeAnnots, reference)
7677
.picklePositions(unit.source, tree :: Nil, positionWarnings)
7778

7879
if !ctx.settings.YdropComments.value then

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,8 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
335335
&& ctx.compilationUnit.source.exists
336336
&& sym != defn.SourceFileAnnot
337337
then
338-
val relativePath = util.SourceFile.relativePath(ctx.compilationUnit.source)
338+
val reference = ctx.settings.sourceroot.value
339+
val relativePath = util.SourceFile.relativePath(ctx.compilationUnit.source, reference)
339340
sym.addAnnotation(Annotation.makeSourceFile(relativePath))
340341
else (tree.rhs, sym.info) match
341342
case (rhs: LambdaTypeTree, bounds: TypeBounds) =>

compiler/src/dotty/tools/dotc/util/SourceFile.scala

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -210,21 +210,32 @@ object SourceFile {
210210
src._maybeInComplete = maybeIncomplete
211211
src
212212

213-
def relativePath(source: SourceFile)(using Context): String = {
214-
def sourcerootPath =
215-
java.nio.file.Paths.get(ctx.settings.sourceroot.value)
216-
.toAbsolutePath
217-
.normalize
213+
/** Returns the relative path of `source` within the `reference` path
214+
*
215+
* It returns the absolute path of `source` if it is not contained in `reference`.
216+
*/
217+
def relativePath(source: SourceFile, reference: String): String = {
218218
val file = source.file
219219
val jpath = file.jpath
220220
if jpath eq null then
221221
file.path // repl and other custom tests use abstract files with no path
222222
else
223-
val normalizedPath = jpath.normalize
224-
// On Windows we can only relativize paths if root component matches
225-
// (see implementation of sun.nio.fs.WindowsPath#relativize)
226-
try sourcerootPath.relativize(normalizedPath).toString
227-
catch case _: IllegalArgumentException => normalizedPath.toString
223+
val sourcePath = jpath.toAbsolutePath.normalize
224+
val refPath = java.nio.file.Paths.get(reference).toAbsolutePath.normalize
225+
226+
if sourcePath.startsWith(refPath) then
227+
// On Windows we can only relativize paths if root component matches
228+
// (see implementation of sun.nio.fs.WindowsPath#relativize)
229+
//
230+
// try refPath.relativize(sourcePath).toString
231+
// catch case _: IllegalArgumentException => sourcePath.toString
232+
//
233+
// As we already check that the prefix matches, the special handling for
234+
// Windows is not needed.
235+
236+
refPath.relativize(sourcePath).toString
237+
else
238+
sourcePath.toString
228239
}
229240
}
230241

language-server/test/dotty/tools/languageserver/util/server/TestFile.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ class TestFile(val file: String) extends AnyVal {
99
}
1010

1111
object TestFile {
12-
lazy val testDir: Path = Paths.get("../out/ide-tests").toAbsolutePath
12+
lazy val testDir: Path = Paths.get("../out/ide-tests").toAbsolutePath.normalize
1313
lazy val sourceDir: Path = testDir.resolve("src")
1414
}

0 commit comments

Comments
 (0)