@@ -6,7 +6,7 @@ import scala.collection.JavaConverters._
6
6
import dotty .tools .dotc .util .SourceFile
7
7
import dotty .tools .dotc .semanticdb .Scala3 .{_ , given }
8
8
9
- object Semanticdbs with
9
+ object Tools with
10
10
11
11
/** Load SemanticDB TextDocument for a single Scala source file
12
12
*
@@ -35,45 +35,33 @@ object Semanticdbs with
35
35
end loadTextDocument
36
36
37
37
/** Parses SemanticDB text documents from an absolute path to a `*.semanticdb` file. */
38
- def parseTextDocuments (path : Path ): TextDocuments =
38
+ private def parseTextDocuments (path : Path ): TextDocuments =
39
39
val bytes = Files .readAllBytes(path) // NOTE: a semanticdb file is a TextDocuments message, not TextDocument
40
40
TextDocuments .parseFrom(bytes)
41
41
42
- /** Prettyprint a text document with symbol occurrences next to each resolved identifier.
43
- *
44
- * Useful for testing purposes to ensure that SymbolOccurrence values make sense and are correct.
45
- * Example output (NOTE, slightly modified to avoid "unclosed comment" errors):
46
- * {{{
47
- * class Example *example/Example#* {
48
- * val a *example/Example#a.* : String *scala/Predef.String#* = "1"
49
- * }
50
- * }}}
51
- **/
52
- def printTextDocument (doc : TextDocument ): String =
53
- val symtab = doc.symbols.iterator.map(info => info.symbol -> info).toMap
54
- val sb = StringBuilder (1000 )
55
- val sourceFile = SourceFile .virtual(doc.uri, doc.text)
56
- var offset = 0
57
- for occ <- doc.occurrences.sorted do
58
- val range = occ.range.get
59
- val end = math.max(
60
- offset,
61
- sourceFile.lineToOffset(range.endLine) + range.endCharacter
62
- )
63
- val isPrimaryConstructor =
64
- symtab.get(occ.symbol).exists(_.isPrimary)
65
- if ! occ.symbol.isPackage && ! isPrimaryConstructor
66
- sb.append(doc.text.substring(offset, end))
67
- sb.append(" /*" )
68
- .append(if (occ.role.isDefinition) " <-" else " ->" )
69
- .append(occ.symbol.replace(" /" , " ::" ))
70
- .append(" */" )
71
- offset = end
72
- sb.append(doc.text.substring(offset))
73
- sb.toString
74
- end printTextDocument
42
+ def metac (doc : TextDocument , realPath : Path )(given sb : StringBuilder ): StringBuilder =
43
+ val realURI = realPath.toString
44
+ given SourceFile = SourceFile .virtual(doc.uri, doc.text)
45
+ sb.append(realURI).nl
46
+ sb.append(" _" * realURI.length).nl
47
+ sb.nl
48
+ sb.append(" Summary:" ).nl
49
+ sb.append(" Schema => " ).append(schemaString(doc.schema)).nl
50
+ sb.append(" Uri => " ).append(doc.uri).nl
51
+ sb.append(" Text => empty" ).nl
52
+ sb.append(" Language => " ).append(languageString(doc.language)).nl
53
+ sb.append(" Symbols => " ).append(doc.symbols.length).append(" entries" ).nl
54
+ sb.append(" Occurrences => " ).append(doc.occurrences.length).append(" entries" ).nl
55
+ sb.nl
56
+ sb.append(" Symbols:" ).nl
57
+ doc.symbols.sorted.foreach(processSymbol)
58
+ sb.nl
59
+ sb.append(" Occurrences:" ).nl
60
+ doc.occurrences.sorted.foreach(processOccurrence)
61
+ sb.nl
62
+ end metac
75
63
76
- def schemaString (schema : Schema ) =
64
+ private def schemaString (schema : Schema ) =
77
65
import Schema ._
78
66
schema match
79
67
case SEMANTICDB3 => " SemanticDB v3"
@@ -82,15 +70,15 @@ object Semanticdbs with
82
70
case Unrecognized (_) => " unknown"
83
71
end schemaString
84
72
85
- def languageString (language : Language ) =
73
+ private def languageString (language : Language ) =
86
74
import Language ._
87
75
language match
88
76
case SCALA => " Scala"
89
77
case JAVA => " Java"
90
78
case UNKNOWN_LANGUAGE | Unrecognized (_) => " unknown"
91
79
end languageString
92
80
93
- def processSymbol (info : SymbolInformation )(given sb : StringBuilder ): Unit =
81
+ private def processSymbol (info : SymbolInformation )(given sb : StringBuilder ): Unit =
94
82
import SymbolInformation .Kind ._
95
83
sb.append(info.symbol).append(" => " )
96
84
if info.isAbstract then sb.append(" abstract " )
@@ -127,7 +115,7 @@ object Semanticdbs with
127
115
sb.append(info.displayName).nl
128
116
end processSymbol
129
117
130
- def processOccurrence (occ : SymbolOccurrence )(given sb : StringBuilder , sourceFile : SourceFile ): Unit =
118
+ private def processOccurrence (occ : SymbolOccurrence )(given sb : StringBuilder , sourceFile : SourceFile ): Unit =
131
119
occ.range match
132
120
case Some (range) =>
133
121
sb.append('[' )
@@ -146,87 +134,4 @@ object Semanticdbs with
146
134
sb.append(if occ.role.isReference then " -> " else " <- " ).append(occ.symbol).nl
147
135
end processOccurrence
148
136
149
- def metac (doc : TextDocument , realPath : Path )(given sb : StringBuilder ): StringBuilder =
150
- val realURI = realPath.toString
151
- given SourceFile = SourceFile .virtual(doc.uri, doc.text)
152
- sb.append(realURI).nl
153
- sb.append(" _" * realURI.length).nl
154
- sb.nl
155
- sb.append(" Summary:" ).nl
156
- sb.append(" Schema => " ).append(schemaString(doc.schema)).nl
157
- sb.append(" Uri => " ).append(doc.uri).nl
158
- sb.append(" Text => empty" ).nl
159
- sb.append(" Language => " ).append(languageString(doc.language)).nl
160
- sb.append(" Symbols => " ).append(doc.symbols.length).append(" entries" ).nl
161
- sb.append(" Occurrences => " ).append(doc.occurrences.length).append(" entries" ).nl
162
- sb.nl
163
- sb.append(" Symbols:" ).nl
164
- doc.symbols.sorted.foreach(processSymbol)
165
- sb.nl
166
- sb.append(" Occurrences:" ).nl
167
- doc.occurrences.sorted.foreach(processOccurrence)
168
- sb.nl
169
- end metac
170
-
171
- /** Sort symbol occurrences by their start position. */
172
- given buildOccurrenceOrdering : Ordering [SymbolOccurrence ] = (x, y) =>
173
- x.range -> y.range match
174
- case None -> _ | _ -> None => 0
175
- case Some (a) -> Some (b) =>
176
- val byLine = Integer .compare(a.startLine, b.startLine)
177
- if (byLine != 0 )
178
- byLine
179
- else // byCharacter
180
- Integer .compare(a.startCharacter, b.startCharacter)
181
- end buildOccurrenceOrdering
182
-
183
- given Ordering [SymbolInformation ] = Ordering .by[SymbolInformation , String ](_.symbol)(IdentifierOrdering ())
184
-
185
- /**
186
- * A comparator for identifier like "Predef" or "Function10".
187
- *
188
- * Differences from the default string comparator:
189
- * - works with CharSequences like compiler `Name`
190
- * - orders numbers by their numerical value instead of lexicographical
191
- * - Good: `Function1`, `Function2`, `Function10`
192
- * - Bad: `Function1`, `Function10`, `Function2`
193
- *
194
- * taken from https://github.com/scalameta/scalameta/blob/master/semanticdb/metap/src/main/scala/scala/meta/internal/metap/IdentifierOrdering.scala
195
- */
196
- class IdentifierOrdering [T <: CharSequence ] extends Ordering [T ] with
197
-
198
- override def compare (o1 : T , o2 : T ): Int =
199
- val len = math.min(o1.length(), o2.length())
200
- var i = 0
201
- while i < len do
202
- val a = o1.charAt(i)
203
- val b = o2.charAt(i)
204
- if a.isDigit && b.isDigit
205
- val byDigit = Integer .compare(toDigit(o1, i), toDigit(o2, i))
206
- if (byDigit != 0 ) return byDigit
207
- else
208
- i = seekNonDigit(o1, i)
209
- else
210
- val result = Character .compare(a, b)
211
- if result != 0
212
- return result
213
- i += 1
214
- end while
215
- Integer .compare(o1.length(), o2.length())
216
- end compare
217
-
218
- private def seekNonDigit (cs : T , i : Int ): Int =
219
- var curr = i
220
- while curr < cs.length && cs.charAt(curr).isDigit do
221
- curr += 1
222
- curr
223
- end seekNonDigit
224
-
225
- private def toDigit (cs : T , i : Int ): Int =
226
- val digit = cs.subSequence(i, seekNonDigit(cs, i))
227
- Integer .parseUnsignedInt(digit.toString)
228
- end toDigit
229
-
230
- end IdentifierOrdering
231
-
232
- inline def (sb : StringBuilder ) nl = sb.append(System .lineSeparator)
137
+ private inline def (sb : StringBuilder ) nl = sb.append(System .lineSeparator)
0 commit comments