Skip to content

Commit a3ceec2

Browse files
committed
self symbols
1 parent 9943ade commit a3ceec2

File tree

4 files changed

+121
-64
lines changed

4 files changed

+121
-64
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package example
2+
3+
class SelfUse extends B { a : B =>
4+
val c = a.b
5+
}

semanticdb/input/src/main/scala/example/Selfs.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package example
22

3-
class B
3+
class B {
4+
val b = 4
5+
}
46

57
class AC1 extends B { self =>
68
}

semanticdb/src/dotty/semanticdb/SemanticdbConsumer.scala

Lines changed: 110 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ class SemanticdbConsumer extends TastyConsumer {
2121
s.TextDocument(text = text, occurrences = occurrences)
2222
}
2323
val package_definitions: Set[Tuple2[String, Int]] = Set()
24+
val symbolsCache: HashMap[(String, s.Range), String] = HashMap()
2425
var local_offset: Int = 0
2526

2627
final def apply(reflect: Reflection)(root: reflect.Tree): Unit = {
2728
import reflect._
2829

29-
val symbolsCache: HashMap[Symbol, String] = HashMap()
3030
val symbolPathsMap: Set[(String, s.Range)] = Set()
3131

3232
object ChildTraverser extends TreeTraverser {
@@ -278,71 +278,86 @@ class SemanticdbConsumer extends TastyConsumer {
278278
}
279279

280280
def iterateParent(symbol: Symbol): String = {
281-
if (symbolsCache.contains(symbol)) {
282-
return symbolsCache(symbol)
281+
if (symbol.name == "<none>" || symbol.name == "<root>") then {
282+
// TODO had a "NoDenotation" test to avoid
283+
// relying on the name itself
284+
""
283285
} else {
284-
val out_symbol_path =
285-
if (symbol.name == "<none>" || symbol.name == "<root>") then {
286-
// TODO had a "NoDenotation" test to avoid
287-
// relying on the name itself
288-
""
289-
} else {
290-
val previous_symbol =
291-
/* When we consider snipper of the form: `abstract class DepAdvD[CC[X[C] <: B], X[Z], C] extends DepTemp`,
286+
val previous_symbol =
287+
/* When we consider snipper of the form: `abstract class DepAdvD[CC[X[C] <: B], X[Z], C] extends DepTemp`,
292288
The symbol for C will be something like example/DepAdvD#`<init>`().[CC].[X].[C].
293289
This is illogic: a init method can't have any child. Thus, when the current symbol is
294290
a typeparameter (or anything), and the owner is an init, we can just "jump" over the init. */
295-
if (symbol.owner.name == "<init>")
296-
iterateParent(symbol.owner.owner)
297-
else
298-
iterateParent(symbol.owner)
299-
300-
val next_atom =
301-
if (symbol.isPackage) {
302-
d.Package(symbol.name)
303-
} else if (symbol.isObject) {
304-
symbol match {
305-
case IsClassSymbol(classsymbol) =>
306-
d.Term(resolveClass(classsymbol).name)
307-
case _ =>
308-
d.Term(symbol.name)
309-
}
310-
} else if (symbol.isMethod) {
311-
d.Method(symbol.name,
312-
disimbiguate(previous_symbol + symbol.name, symbol))
313-
} else if (symbol.isTypeParameter) {
314-
d.TypeParameter(symbol.name)
315-
} else if (symbol.isValueParameter) {
316-
d.Parameter(symbol.name)
317-
} else if (symbol.isType || symbol.isTrait) {
318-
d.Type(symbol.name)
319-
} else {
291+
if (symbol.owner.name == "<init>")
292+
iterateParent(symbol.owner.owner)
293+
else
294+
iterateParent(symbol.owner)
295+
296+
val next_atom =
297+
if (symbol.isPackage) {
298+
d.Package(symbol.name)
299+
} else if (symbol.isObject) {
300+
symbol match {
301+
case IsClassSymbol(classsymbol) =>
302+
d.Term(resolveClass(classsymbol).name)
303+
case _ =>
320304
d.Term(symbol.name)
321-
}
322-
323-
Symbols.Global(previous_symbol, next_atom)
305+
}
306+
} else if (symbol.isMethod) {
307+
d.Method(symbol.name,
308+
disimbiguate(previous_symbol + symbol.name, symbol))
309+
} else if (symbol.isTypeParameter) {
310+
d.TypeParameter(symbol.name)
311+
} else if (symbol.isValueParameter) {
312+
d.Parameter(symbol.name)
313+
} else if (symbol.isType || symbol.isTrait) {
314+
d.Type(symbol.name)
315+
} else {
316+
d.Term(symbol.name)
324317
}
325-
symbolsCache += (symbol -> out_symbol_path)
326-
out_symbol_path
318+
319+
Symbols.Global(previous_symbol, next_atom)
320+
}
321+
}
322+
323+
def addSelfDefinition(name: String, range: s.Range): Unit = {
324+
var localsymbol = Symbols.Local(local_offset.toString)
325+
local_offset += 1
326+
symbolsCache += ((name, range) -> localsymbol)
327+
occurrences =
328+
occurrences :+
329+
s.SymbolOccurrence(
330+
Some(range),
331+
localsymbol,
332+
s.SymbolOccurrence.Role.DEFINITION
333+
)
334+
}
335+
336+
def symbolToSymbolString(symbol: Symbol): (String, Boolean) = {
337+
if (symbol.isSemanticdbLocal) {
338+
var localsymbol = Symbols.Local(local_offset.toString)
339+
local_offset += 1
340+
(localsymbol, false)
341+
} else {
342+
(iterateParent(symbol), true)
327343
}
328344
}
329345

330346
def addOccurence(symbol: Symbol,
331347
type_symbol: s.SymbolOccurrence.Role,
332348
range: s.Range): Unit = {
333-
val (symbol_path, is_global) =
334-
if (symbol.isSemanticdbLocal) {
335-
if (symbolsCache.contains(symbol)) {
336-
(symbolsCache(symbol), false)
337-
} else {
338-
var localsymbol = Symbols.Local(local_offset.toString)
339-
local_offset += 1
340-
symbolsCache += (symbol -> localsymbol)
341-
(localsymbol, false)
342-
}
343-
} else {
344-
(iterateParent(symbol), true)
349+
val (symbol_path, is_global) = posToRange(symbol.pos) match {
350+
case Some(keyRange)
351+
if symbolsCache.contains((symbol.name, keyRange)) =>
352+
(symbolsCache((symbol.name, keyRange)), symbol.isSemanticdbLocal)
353+
case Some(keyRange) => {
354+
val (sp, ig) = symbolToSymbolString(symbol)
355+
symbolsCache += ((symbol.name, keyRange) -> sp)
356+
(sp, ig)
345357
}
358+
case _ =>
359+
symbolToSymbolString(symbol)
360+
}
346361

347362
if (symbol_path == "" || symbol.isUselessOccurrence) return
348363
println(symbol_path, range, symbol.owner.flags)
@@ -366,7 +381,8 @@ class SemanticdbConsumer extends TastyConsumer {
366381
type_symbol: s.SymbolOccurrence.Role,
367382
range: s.Range,
368383
force_add: Boolean = false): Unit = {
369-
if (tree.isUserCreated || (force_add && !(!tree.isUserCreated && iterateParent(tree.symbol) == "java/lang/Object#`<init>`()."))) {
384+
if (tree.isUserCreated || (force_add && !(!tree.isUserCreated && iterateParent(
385+
tree.symbol) == "java/lang/Object#`<init>`()."))) {
370386
addOccurence(tree.symbol, type_symbol, range)
371387
}
372388
}
@@ -392,6 +408,18 @@ class SemanticdbConsumer extends TastyConsumer {
392408
)
393409
}
394410

411+
def posToRange(pos: Position): Option[s.Range] = {
412+
if (pos.exists) {
413+
Some(
414+
s.Range(pos.startLine,
415+
pos.startColumn,
416+
pos.startLine,
417+
pos.endColumn))
418+
} else {
419+
None
420+
}
421+
}
422+
395423
def range(tree: Tree, pos: Position, name: String): s.Range = {
396424
val offset = tree match {
397425
case IsPackageClause(tree) => "package ".length
@@ -520,10 +548,11 @@ class SemanticdbConsumer extends TastyConsumer {
520548
tree.symbol.pos.startLine,
521549
tree.symbol.pos.startColumn + classname.length + 1))
522550
} else {
523-
fittedInitClassRange = Some(s.Range(constr.symbol.pos.startLine,
524-
constr.symbol.pos.startColumn,
525-
constr.symbol.pos.endLine,
526-
constr.symbol.pos.endColumn))
551+
fittedInitClassRange = Some(
552+
s.Range(constr.symbol.pos.startLine,
553+
constr.symbol.pos.startColumn,
554+
constr.symbol.pos.endLine,
555+
constr.symbol.pos.endColumn))
527556
}
528557
traverseTree(constr)
529558
fittedInitClassRange = None
@@ -532,13 +561,30 @@ class SemanticdbConsumer extends TastyConsumer {
532561
forceAddBecauseParents = true
533562
parents.foreach(_ match {
534563
case IsTypeTree(t) => traverseTypeTree(t)
535-
case IsTerm(t) => traverseTree(t)
564+
case IsTerm(t) => {println(t.pos.startColumn, t.pos.endColumn)
565+
traverseTree(t)}
536566
})
537567
forceAddBecauseParents = false
538568

539-
selfopt.foreach(traverseTree)
540569

541570

571+
selfopt match {
572+
case Some(vdef @ ValDef(name, _, _)) => {
573+
val posColumn : Int = parents.foldLeft(vdef.pos.startColumn)((old : Int, ct : TermOrTypeTree) =>
574+
ct match {
575+
case IsTerm(t) => if (t.pos.endColumn + 3 < old) {t.pos.endColumn+3} else {old}
576+
case _ => old
577+
})
578+
println(posColumn)
579+
println(vdef)
580+
println(vdef.pos.startColumn, tree.pos.startColumn, tree.pos.endColumn)
581+
addSelfDefinition(name, s.Range(vdef.pos.startLine, posColumn, vdef.pos.endLine, posColumn + name.length))
582+
println(name)
583+
}
584+
case _ =>
585+
}
586+
selfopt.foreach(traverseTree)
587+
542588
statements.foreach(traverseTree)
543589
}
544590
case IsDefinition(cdef) => {
@@ -593,7 +639,10 @@ class SemanticdbConsumer extends TastyConsumer {
593639
super.traverseTree(cdef)
594640
}
595641

596-
case Term.Select(qualifier, _) => {
642+
case Term.This(what) =>
643+
addOccurenceTree(tree, s.SymbolOccurrence.Role.REFERENCE, posToRange(tree.pos).get)
644+
645+
case Term.Select(qualifier, _, _) => {
597646
val range = {
598647
val r = rangeSelect(tree.symbol.name, tree.pos)
599648
if (tree.symbol.name == "<init>")

semanticdb/test/dotty/semanticdb/Tests.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ class Tests {
178178
//@Test def testAccess(): Unit = checkFile("example/Access.scala")
179179
//@Test def testAdvanced(): Unit = checkFile("example/Advanced.scala")
180180
//@Test def testAnonymous(): Unit = checkFile("example/Anonymous.scala")
181-
@Test def testClasses(): Unit = checkFile("example/Classes.scala")
181+
//@Test def testClasses(): Unit = checkFile("example/Classes.scala")
182182
//@Test def testEmpty(): Unit = checkFile("example/Empty.scala")
183183
//@Test def testEmptyObject(): Unit = checkFile("example/EmptyObject.scala")
184184
//@Test def testExample(): Unit = checkFile("example/Example.scala")
@@ -196,7 +196,8 @@ class Tests {
196196
//def testObjects(): Unit = checkFile("example/Objects.scala")
197197
//@Test def testOverrides(): Unit = checkFile("example/Overrides.scala")
198198
//WIP @Test def testPrefixes(): Unit = checkFile("example/Prefixes.scala")
199-
//@Test def testSelfs(): Unit = checkFile("example/Selfs.scala")
199+
@Test def testSelfs(): Unit = checkFile("example/Selfs.scala")
200+
@Test def testSelfUse(): Unit = checkFile("example/SelfUse.scala")
200201
//WIP @Test def testSynthetic(): Unit = checkFile("example/Synthetic.scala")
201202
//WIP @Test def testTraits(): Unit = checkFile("example/Traits.scala")
202203
//WIP @Test def testTypes(): Unit = checkFile("example/Types.scala")

0 commit comments

Comments
 (0)