@@ -106,7 +106,7 @@ class SemanticdbConsumer(sourceFile: java.nio.file.Path) extends TastyConsumer {
106
106
case _ => false
107
107
}
108
108
109
- def isTypeParameter : Boolean = symbol.flags.is( Flags . Param ) && symbol.isType
109
+ def isTypeParameter : Boolean = symbol.isParameter && symbol.isType
110
110
111
111
def isType : Boolean = symbol match {
112
112
case IsTypeSymbol (_) => true
@@ -128,13 +128,21 @@ class SemanticdbConsumer(sourceFile: java.nio.file.Path) extends TastyConsumer {
128
128
def isDefaultGetter : Boolean =
129
129
symbol.name.contains(tpnme.DEFAULT_GETTER .toString)
130
130
131
+ def isReservedName : Boolean = {
132
+ val keywords =
133
+ List (" ev$" , " evidence$" , " $_lazy_implicit_$" , " $lzy" , " $lzyINIT" ,
134
+ " $OFFSET" , " bitmap$" , " _$" , " $tailLocal" , " tmp" , " $doc" ,
135
+ " $superArg$" , " $scrutinee" , " $elem" )
136
+ return keywords.exists(symbol.name.contains(_))
137
+ }
138
+
131
139
def isParameter : Boolean = symbol.flags.is(Flags .Param )
132
140
133
141
def isObject : Boolean = symbol.flags.is(Flags .Object )
134
142
135
143
def isTrait : Boolean = symbol.flags.is(Flags .Trait )
136
144
137
- def isValueParameter : Boolean = symbol.flags.is( Flags . Param )
145
+ def isValueParameter : Boolean = symbol.isParameter && ! symbol.isType
138
146
139
147
def isJavaClass : Boolean = symbol.isClass && symbol.flags.is(Flags .JavaDefined )
140
148
@@ -263,6 +271,7 @@ class SemanticdbConsumer(sourceFile: java.nio.file.Path) extends TastyConsumer {
263
271
264
272
def isUseless (implicit ctx : Context ): Boolean = {
265
273
symbol == NoSymbol ||
274
+ symbol.isReservedName ||
266
275
// symbol.isInitChild ||
267
276
symbol.isAnonymousInit ||
268
277
symbol.isDefaultGetter ||
@@ -347,14 +356,14 @@ class SemanticdbConsumer(sourceFile: java.nio.file.Path) extends TastyConsumer {
347
356
case _ =>
348
357
d.Term (symbol.trueName)
349
358
}
359
+ } else if (symbol.isValueParameter) {
360
+ d.Parameter (symbol.trueName)
350
361
} else if (symbol.isMethod || symbol.isUsefulField) {
351
362
d.Method (symbol.trueName,
352
363
disimbiguate(previous_symbol + symbol.trueName, symbol))
353
364
} else if (symbol.isTypeParameter) {
354
365
d.TypeParameter (symbol.trueName)
355
- } else if (symbol.isValueParameter) {
356
- d.Parameter (symbol.trueName)
357
- } else if (symbol.isType || symbol.isTrait) {
366
+ } else if (symbol.isType || symbol.isTrait) {
358
367
d.Type (symbol.trueName)
359
368
} else {
360
369
d.Term (symbol.trueName)
@@ -413,6 +422,8 @@ class SemanticdbConsumer(sourceFile: java.nio.file.Path) extends TastyConsumer {
413
422
case _ =>
414
423
symbolToSymbolString(symbol)
415
424
}
425
+
426
+ println(symbol_path)
416
427
// We want to add symbols coming from our file
417
428
// if (symbol.pos.sourceFile != sourceFile) return
418
429
if (symbol_path == " " || symbol.isUselessOccurrence) return
@@ -426,9 +437,9 @@ class SemanticdbConsumer(sourceFile: java.nio.file.Path) extends TastyConsumer {
426
437
// dotty will generate a ValDef for the x, but the x will also
427
438
// be present in the constructor, thus making a double definition
428
439
if (symbolPathsMap.contains(key)) return
429
- if (is_global) {
440
+ // if (is_global) {
430
441
symbolPathsMap += key
431
- }
442
+ // }
432
443
println(symbol_path,
433
444
range,
434
445
symbol.flags,
@@ -589,13 +600,50 @@ class SemanticdbConsumer(sourceFile: java.nio.file.Path) extends TastyConsumer {
589
600
s.SymbolOccurrence .Role .REFERENCE ,
590
601
range)
591
602
super .traverseTypeTree(typetree)
592
- }/*
603
+ }
604
+
605
+ case TypeTree .Projection (qualifier, x) => {
606
+ val typetree = extractTypeTree(tree)
607
+ val range = rangeSelect(typetree.symbol.trueName, typetree.pos)
608
+ addOccurenceTypeTree(typetree,
609
+ s.SymbolOccurrence .Role .REFERENCE ,
610
+ range)
611
+ super .traverseTypeTree(typetree)
612
+ }
613
+
593
614
case TypeTree .Inferred () => {
615
+ /* In theory no inferred types should be put in the semanticdb file.
616
+ However, take the case where a typed is refered from an imported class:
617
+ class PrefC {
618
+ object N {
619
+ type U
620
+ }
621
+ }
622
+
623
+ object PrefTest {
624
+ val c: PrefC = ???
625
+ import c.N._
626
+ def k3: U = ???
627
+ }
628
+
629
+ The type corresponding to U in the definition of k3 is marked as
630
+ inferred even though it is present in the source code. We use a
631
+ workaround for this specific case, by checking if the name of the
632
+ inferred type corresponds to the one put in the source code at this
633
+ position
634
+ */
635
+
594
636
val typetree = extractTypeTree(tree)
595
- addOccurenceTypeTree(typetree,
637
+ val start = typetree.pos.start
638
+ val end = typetree.pos.end
639
+ if (end < sourceCode.length
640
+ && sourceCode.substring(start, end) == typetree.symbol.name) {
641
+ addOccurenceTypeTree(typetree,
596
642
s.SymbolOccurrence .Role .REFERENCE ,
597
643
posToRange(typetree.pos).get)
598
- }*/
644
+ }
645
+ }
646
+
599
647
case _ => {
600
648
super .traverseTypeTree(tree)
601
649
}
@@ -622,6 +670,7 @@ class SemanticdbConsumer(sourceFile: java.nio.file.Path) extends TastyConsumer {
622
670
623
671
var fittedInitClassRange : Option [s.Range ] = None
624
672
var forceAddBecauseParents : Boolean = false
673
+ var classStacks : List [Symbol ] = Nil
625
674
626
675
def getNumberParametersInit (defdef : DefDef )(implicit ctx : Context ): Int = {
627
676
defdef match {
@@ -646,7 +695,6 @@ class SemanticdbConsumer(sourceFile: java.nio.file.Path) extends TastyConsumer {
646
695
super .traverseTree(tree)
647
696
}
648
697
case ClassDef (classname, constr, parents, selfopt, statements) => {
649
-
650
698
// we first add the class to the symbol list
651
699
addOccurenceTree(tree,
652
700
s.SymbolOccurrence .Role .DEFINITION ,
@@ -677,39 +725,46 @@ class SemanticdbConsumer(sourceFile: java.nio.file.Path) extends TastyConsumer {
677
725
}
678
726
})
679
727
forceAddBecauseParents = false
680
-
681
728
selfopt match {
682
- case Some (vdef @ ValDef (name, type_, _)) if name != " _" => {
683
- // To find the current position, we will heuristically
684
- // reparse the source code.
685
- // The process is done in three steps:
686
- // 1) Find a position before the '{' of the self but after any
687
- // non related '{'. Here, it will be the largest end pos of a parent
688
- // 2) Find the first '{'
689
- // 3) Iterate until the character we are seeing is a letter
690
- val startPosSearch : Int = parents.foldLeft(tree.pos.end)(
691
- (old : Int , ct : TermOrTypeTree ) =>
692
- ct match {
693
- case IsTerm (t) if t.pos.end < old => t.pos.end
694
- case _ => old
695
- })
696
- var posColumn = sourceCode.indexOf(" {" , if (startPosSearch == tree.pos.end) tree.pos.start else startPosSearch)
697
-
698
- while (posColumn < sourceCode.length && ! sourceCode(posColumn).isLetter) posColumn += 1
699
-
700
- addSelfDefinition(name,
701
- s.Range (0 ,
702
- posColumn,
703
- 0 ,
704
- posColumn + name.length))
729
+ case Some (vdef @ ValDef (name, type_, _)) => {
730
+ // If name is "_" then it means it is in fact "this". We don't
731
+ // want to had a symbol for it in semanticdb
732
+ if (name != " _" ) {
733
+ // The tree does not include a position to the overloaded version of
734
+ // this. We find it heuristically by "parsing" the source code.
735
+ // The process is done in three steps:
736
+ // 1) Find a position before the '{' of the self but after any
737
+ // non related '{'. Here, it will be the largest end pos of a parent
738
+ // 2) Find the first '{'
739
+ // 3) Iterate until the character we are seeing is a letter
740
+ val startPosSearch : Int = parents.foldLeft(tree.pos.end)(
741
+ (old : Int , ct : TermOrTypeTree ) =>
742
+ ct match {
743
+ case IsTerm (t) if t.pos.end < old => t.pos.end
744
+ case _ => old
745
+ })
746
+ var posColumn = sourceCode.indexOf(" {" , if (startPosSearch == tree.pos.end) tree.pos.start else startPosSearch)
747
+
748
+ while (posColumn < sourceCode.length && ! sourceCode(posColumn).isLetter) posColumn += 1
749
+
750
+ addSelfDefinition(name,
751
+ s.Range (0 ,
752
+ posColumn,
753
+ 0 ,
754
+ posColumn + name.length))
755
+ }
705
756
println(type_)
706
757
traverseTypeTree(type_)
707
758
}
708
759
case _ =>
709
760
}
710
761
762
+ classStacks = tree.symbol :: classStacks
763
+
711
764
statements.takeRight(statements.length - getNumberParametersInit(constr)).foreach(traverseTree)
712
765
766
+ classStacks = classStacks.tail
767
+
713
768
}
714
769
case IsDefinition (cdef) => {
715
770
@@ -761,12 +816,22 @@ class SemanticdbConsumer(sourceFile: java.nio.file.Path) extends TastyConsumer {
761
816
super .traverseTree(cdef)
762
817
}
763
818
764
- case Term .This (what) =>
819
+ case Term .This (Some (_)) => {
765
820
addOccurenceTree(tree,
766
821
s.SymbolOccurrence .Role .REFERENCE ,
767
822
posToRange(tree.pos).get)
823
+ }
824
+
825
+ case Term .Super (_, Some (id)) =>
826
+ {
827
+ addOccurence(classStacks.head,
828
+ s.SymbolOccurrence .Role .DEFINITION ,
829
+ posToRange(id.pos).get)
830
+ super .traverseTree(tree)
831
+ }
768
832
769
833
case Term .Select (qualifier, _) => {
834
+ println(" SELECT => " + tree)
770
835
val range = {
771
836
val r = rangeSelect(tree.symbol.trueName, tree.pos)
772
837
if (tree.symbol.trueName == " <init>" )
0 commit comments