@@ -16,7 +16,7 @@ import scala.tools.nsc.ast._
16
16
import scala .tools .nsc .io .Pickler ._
17
17
import scala .tools .nsc .typechecker .DivergentImplicit
18
18
import scala .annotation .tailrec
19
- import scala .reflect .generic .Flags .LOCKED
19
+ import scala .reflect .generic .Flags .{ ACCESSOR , PARAMACCESSOR }
20
20
21
21
/** The main class of the presentation compiler in an interactive environment such as an IDE
22
22
*/
@@ -45,7 +45,7 @@ self =>
45
45
else NullLogger
46
46
47
47
import log .logreplay
48
- debugLog(" interactive compiler from 3 Feb" )
48
+ debugLog(" interactive compiler from 9 Feb" )
49
49
debugLog(" logger: " + log.getClass + " writing to " + (new java.io.File (logName)).getAbsolutePath)
50
50
debugLog(" classpath: " + classPath)
51
51
@@ -270,9 +270,9 @@ self =>
270
270
case _ =>
271
271
}
272
272
273
- lastWasReload = false
273
+ lastWasReload = false
274
274
275
- logreplay(" workitem" , scheduler.nextWorkItem()) match {
275
+ logreplay(" workitem" , scheduler.nextWorkItem()) match {
276
276
case Some (action) =>
277
277
try {
278
278
debugLog(" picked up work item at " + pos+ " : " + action)
@@ -619,22 +619,49 @@ self =>
619
619
620
620
val Dollar = newTermName(" $" )
621
621
622
+ class Members [M <: Member ] extends LinkedHashMap [Name , Set [M ]] {
623
+ override def default (key : Name ) = Set ()
624
+
625
+ private def matching (sym : Symbol , symtpe : Type , ms : Set [M ]): Option [M ] = ms.find { m =>
626
+ (m.sym.name == sym.name) && (m.sym.isType || (m.tpe matches symtpe))
627
+ }
628
+
629
+ private def keepSecond (m : M , sym : Symbol , implicitlyAdded : Boolean ): Boolean =
630
+ m.sym.hasFlag(ACCESSOR | PARAMACCESSOR ) &&
631
+ ! sym.hasFlag(ACCESSOR | PARAMACCESSOR ) &&
632
+ (! implicitlyAdded || m.implicitlyAdded)
633
+
634
+ def add (sym : Symbol , pre : Type , implicitlyAdded : Boolean )(toMember : (Symbol , Type ) => M ) {
635
+ if ((sym.isGetter || sym.isSetter) && sym.accessed != NoSymbol ) {
636
+ add(sym.accessed, pre, implicitlyAdded)(toMember)
637
+ } else if (! sym.name.decode.containsName(Dollar ) && ! sym.isSynthetic && sym.hasRawInfo) {
638
+ val symtpe = pre.memberType(sym) onTypeError ErrorType
639
+ matching(sym, symtpe, this (sym.name)) match {
640
+ case Some (m) =>
641
+ if (keepSecond(m, sym, implicitlyAdded)) {
642
+ // print(" -+ "+sym.name)
643
+ this (sym.name) = this (sym.name) - m + toMember(sym, symtpe)
644
+ }
645
+ case None =>
646
+ // print(" + "+sym.name)
647
+ this (sym.name) = this (sym.name) + toMember(sym, symtpe)
648
+ }
649
+ }
650
+ }
651
+
652
+ def allMembers : List [M ] = values.toList.flatten
653
+ }
654
+
622
655
/** Return all members visible without prefix in context enclosing `pos`. */
623
656
def scopeMembers (pos : Position ): List [ScopeMember ] = {
624
657
typedTreeAt(pos) // to make sure context is entered
625
658
val context = doLocateContext(pos)
626
- val locals = new LinkedHashMap [ Name , ScopeMember ]
659
+ val locals = new Members [ ScopeMember ]
627
660
def addScopeMember (sym : Symbol , pre : Type , viaImport : Tree ) =
628
- if (! sym.name.decode.containsName(Dollar ) &&
629
- ! sym.isSynthetic &&
630
- sym.hasRawInfo &&
631
- ! locals.contains(sym.name)) {
632
- locals(sym.name) = new ScopeMember (
633
- sym,
634
- pre.memberType(sym) onTypeError ErrorType ,
635
- context.isAccessible(sym, pre, false ),
636
- viaImport)
661
+ locals.add(sym, pre, false ) { (s, st) =>
662
+ new ScopeMember (s, st, context.isAccessible(s, pre, false ), viaImport)
637
663
}
664
+ // print("add scope members")
638
665
var cx = context
639
666
while (cx != NoContext ) {
640
667
for (sym <- cx.scope)
@@ -646,14 +673,15 @@ self =>
646
673
}
647
674
cx = cx.outer
648
675
}
649
-
676
+ // print("\nadd imported members")
650
677
for (imp <- context.imports) {
651
678
val pre = imp.qual.tpe
652
679
for (sym <- imp.allImportedSymbols) {
653
680
addScopeMember(sym, pre, imp.qual)
654
681
}
655
682
}
656
- val result = locals.values.toList
683
+ // println()
684
+ val result = locals.allMembers
657
685
// if (debugIDE) for (m <- result) println(m)
658
686
result
659
687
}
@@ -683,17 +711,13 @@ self =>
683
711
debugLog(" typeMembers at " + tree+ " " + tree.tpe)
684
712
685
713
val superAccess = tree.isInstanceOf [Super ]
686
- val scope = new Scope
687
- val members = new LinkedHashMap [Symbol , TypeMember ]
688
-
689
- def addTypeMember (sym : Symbol , pre : Type , inherited : Boolean , viaView : Symbol ) {
690
- val symtpe = pre.memberType(sym) onTypeError ErrorType
691
- if (scope.lookupAll(sym.name) forall (sym => ! (members(sym).tpe matches symtpe))) {
692
- scope enter sym
693
- members(sym) = new TypeMember (
694
- sym,
695
- symtpe,
696
- context.isAccessible(sym, pre, superAccess && (viaView == NoSymbol )),
714
+ val members = new Members [TypeMember ]
715
+
716
+ def addTypeMember (sym : Symbol , pre : Type , inherited : Boolean , viaView : Symbol ) = {
717
+ val implicitlyAdded = viaView != NoSymbol
718
+ members.add(sym, pre, implicitlyAdded) { (s, st) =>
719
+ new TypeMember (s, st,
720
+ context.isAccessible(s, pre, superAccess && ! implicitlyAdded),
697
721
inherited,
698
722
viaView)
699
723
}
@@ -708,37 +732,32 @@ self =>
708
732
.onTypeError(EmptyTree )
709
733
}
710
734
711
- /** Names containing $ are not valid completions. */
712
- def shouldDisplay (sym : Symbol ): Boolean =
713
- ! sym.name.toString.contains(" $" )
714
-
715
735
val pre = stabilizedType(tree)
716
736
val ownerTpe = tree.tpe match {
717
737
case analyzer.ImportType (expr) => expr.tpe
718
738
case null => pre
719
739
case _ => tree.tpe
720
740
}
721
741
722
- for (sym <- ownerTpe.decls if shouldDisplay(sym))
742
+ // print("add members")
743
+ for (sym <- ownerTpe.members)
723
744
addTypeMember(sym, pre, false , NoSymbol )
724
- members.values.toList #:: {
725
- for (sym <- ownerTpe.members if shouldDisplay(sym))
726
- addTypeMember(sym, pre, true , NoSymbol )
727
- members.values.toList #:: {
728
- val applicableViews : List [SearchResult ] =
729
- if (ownerTpe.isErroneous) List ()
730
- else new ImplicitSearch (
731
- tree, functionType(List (ownerTpe), AnyClass .tpe), isView = true ,
732
- context.makeImplicit(reportAmbiguousErrors = false )).allImplicits
733
- for (view <- applicableViews) {
734
- val vtree = viewApply(view)
735
- val vpre = stabilizedType(vtree)
736
- for (sym <- vtree.tpe.members) {
737
- addTypeMember(sym, vpre, false , view.tree.symbol)
738
- }
745
+ members.allMembers #:: {
746
+ // print("\nadd pimped")
747
+ val applicableViews : List [SearchResult ] =
748
+ if (ownerTpe.isErroneous) List ()
749
+ else new ImplicitSearch (
750
+ tree, functionType(List (ownerTpe), AnyClass .tpe), isView = true ,
751
+ context.makeImplicit(reportAmbiguousErrors = false )).allImplicits
752
+ for (view <- applicableViews) {
753
+ val vtree = viewApply(view)
754
+ val vpre = stabilizedType(vtree)
755
+ for (sym <- vtree.tpe.members) {
756
+ addTypeMember(sym, vpre, false , view.tree.symbol)
739
757
}
740
- Stream (members.values.toList)
741
758
}
759
+ // println()
760
+ Stream (members.allMembers)
742
761
}
743
762
}
744
763
0 commit comments