From 04df2e48e4ae53a4f72c299ce88fa2239b7fba69 Mon Sep 17 00:00:00 2001 From: Mirco Dotta Date: Wed, 16 Oct 2013 13:57:13 +0200 Subject: SI-7915 Corrected range positions created during default args expansion The tree created during expansion of default arguments contained trees with the wrong type of positions. Let's discuss this with an example. Below is the tree generated for the `foo` method in the test class included in this commit. Before this commit: ``` [54:94]def foo(): [58]Unit = <70:90>{ [70:79] val qual$1: [70]Bar = [70:79][70:79][70:79]new [74:77]Bar(); [80] val x$1: [80]Int = [80]qual$1.bar$default$1; <70:90><70:83>qual$1.bar([80]x$1) } ``` Now: ``` [54:99]def foo(): [58]Unit = <70:95>{ <70:84> val qual$1: [70]Bar = [70:84][70:84][70:84]new [74:77]Bar(); [85] val x$1: [85]Int = [85]qual$1.bar$default$1; <70:95>[84:88]qual$1.bar([85]x$1) } ``` Here are the list of changes: * The synthetic `qual$1` has a transparent position, instead of a range position. * The new Select tree (i.e., `qual$1.bar`) should always have a range position, because `selected` (i.e., the called method) is always visible in the source (in fact, this is the whole point of the fix, we need a range position or hyperlinking request from the Scala IDE won't work). * The Block that contains the expanded default arguments is forced to have a transparent position, as it never exist in the original source. The tricky part of the fix is the position assigned to the new Select tree, which needs to respect the range position's invariants. In the specific case, we ought to make sure that range positions don't overlap. Therefore, the position assigned to the new Select tree is computed by intersecting the original Select position (i.e., `baseFun`'s position) and the original qualifier's position (i.e., `qual`'s position). If you take a closer look at the range positions assigned in the tree after this commit, you'll notice that the range position of the `qual$1`'s rhs (i.e., [70:84]), and `qual$1.bar` (i.e., [84:88]) might seem to overlap, because the former ends where the latter begins. However, this not the case because of the range position's invariant 2, which states: > Invariant 2: in a range position, start <= point < end Hence, the above two positions aren't overlapping as far as the compiler is concerned. One additional aspect (that may look like a detail) is that we make sure to never generate a position such that its start is after its end. This is why we take the position with the smallest end point. Furthermore, calling `withStart` would turn any position in a range position, which isn't desiderable in general (and, even worse, this can lead to generation of invalid positions - bad offsets - if the computation is performed on offset positions). Hence, the position's computation is only performed when both `baseFun` and `qual` positions are range positions. Indeed, I expect this to be always the case if the compiler is started with -Yrangepos. (cherry picked from commit 3009a525b58a4c7865ff524899b85518884ee5f7) --- src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala | 9 ++++++--- test/files/presentation/t7915.check | 11 +++++++++++ test/files/presentation/t7915/Test.scala | 8 ++++++++ test/files/presentation/t7915/src/Foo.scala | 9 +++++++++ 4 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 test/files/presentation/t7915.check create mode 100644 test/files/presentation/t7915/Test.scala create mode 100644 test/files/presentation/t7915/src/Foo.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index aafff8a48e..70f2f41ec7 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -164,7 +164,7 @@ trait NamesDefaults { self: Analyzer => // never used for constructor calls, they always have a stable qualifier def blockWithQualifier(qual: Tree, selected: Name) = { - val sym = blockTyper.context.owner.newValue(unit.freshTermName("qual$"), qual.pos) setInfo uncheckedBounds(qual.tpe) + val sym = blockTyper.context.owner.newValue(unit.freshTermName("qual$"), qual.pos) setInfo uncheckedBounds(qual.tpe) setPos (qual.pos.makeTransparent) blockTyper.context.scope enter sym val vd = atPos(sym.pos)(ValDef(sym, qual) setType NoType) // it stays in Vegas: SI-5720, SI-5727 @@ -175,13 +175,16 @@ trait NamesDefaults { self: Analyzer => // setSymbol below is important because the 'selected' function might be overloaded. by // assigning the correct method symbol, typedSelect will just assign the type. the reason // to still call 'typed' is to correctly infer singleton types, SI-5259. - val f = blockTyper.typedOperator(Select(newQual, selected).setSymbol(baseFun1.symbol)) + val selectPos = + if(qual.pos.isRange && baseFun.pos.isRange) qual.pos.union(baseFun.pos).withStart(Math.min(qual.pos.end, baseFun.pos.end)) + else baseFun.pos + val f = blockTyper.typedOperator(Select(newQual, selected).setSymbol(baseFun1.symbol).setPos(selectPos)) if (funTargs.isEmpty) f else TypeApply(f, funTargs).setType(baseFun.tpe) } val b = Block(List(vd), baseFunTransformed) - .setType(baseFunTransformed.tpe).setPos(baseFun.pos) + .setType(baseFunTransformed.tpe).setPos(baseFun.pos.makeTransparent) context.namedApplyBlockInfo = Some((b, NamedApplyInfo(Some(newQual), defaultTargs, Nil, blockTyper))) b diff --git a/test/files/presentation/t7915.check b/test/files/presentation/t7915.check new file mode 100644 index 0000000000..b18b4ddb55 --- /dev/null +++ b/test/files/presentation/t7915.check @@ -0,0 +1,11 @@ +reload: Foo.scala + +askHyperlinkPos for `Bar` at (7,11) Foo.scala +================================================================================ +[response] found askHyperlinkPos for `Bar` at (1,7) Foo.scala +================================================================================ + +askHyperlinkPos for `bar` at (7,22) Foo.scala +================================================================================ +[response] found askHyperlinkPos for `bar` at (2,7) Foo.scala +================================================================================ diff --git a/test/files/presentation/t7915/Test.scala b/test/files/presentation/t7915/Test.scala new file mode 100644 index 0000000000..c2f89bdb17 --- /dev/null +++ b/test/files/presentation/t7915/Test.scala @@ -0,0 +1,8 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest + +object Test extends InteractiveTest { + override def runDefaultTests() { + sourceFiles foreach (src => askLoadedTyped(src).get) + super.runDefaultTests() + } +} diff --git a/test/files/presentation/t7915/src/Foo.scala b/test/files/presentation/t7915/src/Foo.scala new file mode 100644 index 0000000000..a4166ae5b4 --- /dev/null +++ b/test/files/presentation/t7915/src/Foo.scala @@ -0,0 +1,9 @@ +class Bar { + def bar(b: Int = 2) {} +} + +class Foo { + def foo() { + new Bar/*#*/().bar/*#*/() + } +} -- cgit v1.2.3 From 3a8796da1a321b5b7bb547c3c0cd9f62b5d0279d Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 6 Nov 2013 15:38:02 +0100 Subject: [nomaster] Test infrastructure for scope completion Adds a new marker /*_*/ to trigger scope completion test. Original type completion test oracles update for the tweaked output (cherry picked from commit 9c7c66ff7907e3ab814f0f4375eeaf6cdd230d5e) --- .../nsc/interactive/tests/InteractiveTest.scala | 2 +- .../nsc/interactive/tests/core/AskCommand.scala | 19 +++++++-- .../nsc/interactive/tests/core/CoreTestDefs.scala | 47 ++++++++++++++++++---- .../nsc/interactive/tests/core/TestMarker.scala | 4 +- test/files/presentation/callcc-interpreter.check | 2 +- .../presentation/completion-implicit-chained.check | 2 +- test/files/presentation/ide-bug-1000349.check | 2 +- test/files/presentation/ide-bug-1000475.check | 6 +-- test/files/presentation/ide-bug-1000531.check | 2 +- test/files/presentation/implicit-member.check | 2 +- test/files/presentation/ping-pong.check | 4 +- test/files/presentation/t5708.check | 2 +- test/files/presentation/visibility.check | 10 ++--- 13 files changed, 76 insertions(+), 28 deletions(-) diff --git a/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala b/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala index 597b9012ce..1c722ea3a0 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala +++ b/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala @@ -69,7 +69,7 @@ abstract class InteractiveTest * Override this member if you need to change the default set of executed test actions. */ protected lazy val testActions: ListBuffer[PresentationCompilerTestDef] = { - ListBuffer(new CompletionAction(compiler), new TypeAction(compiler), new HyperlinkAction(compiler)) + ListBuffer(new TypeCompletionAction(compiler), new ScopeCompletionAction(compiler), new TypeAction(compiler), new HyperlinkAction(compiler)) } /** Add new presentation compiler actions to test. Presentation compiler's test diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/AskCommand.scala b/src/compiler/scala/tools/nsc/interactive/tests/core/AskCommand.scala index 8d446cbbf8..4f9df6808f 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/core/AskCommand.scala +++ b/src/compiler/scala/tools/nsc/interactive/tests/core/AskCommand.scala @@ -42,7 +42,7 @@ trait AskParse extends AskCommand { import compiler.Tree /** `sources` need to be entirely parsed before running the test - * (else commands such as `AskCompletionAt` may fail simply because + * (else commands such as `AskTypeCompletionAt` may fail simply because * the source's AST is not yet loaded). */ def askParse(sources: Seq[SourceFile]) { @@ -72,10 +72,10 @@ trait AskReload extends AskCommand { } /** Ask the presentation compiler for completion at a given position. */ -trait AskCompletionAt extends AskCommand { +trait AskTypeCompletionAt extends AskCommand { import compiler.Member - private[tests] def askCompletionAt(pos: Position)(implicit reporter: Reporter): Response[List[Member]] = { + private[tests] def askTypeCompletionAt(pos: Position)(implicit reporter: Reporter): Response[List[Member]] = { reporter.println("\naskTypeCompletion at " + pos.source.file.name + ((pos.line, pos.column))) ask { @@ -84,6 +84,19 @@ trait AskCompletionAt extends AskCommand { } } +/** Ask the presentation compiler for scope completion at a given position. */ +trait AskScopeCompletionAt extends AskCommand { + import compiler.Member + + private[tests] def askScopeCompletionAt(pos: Position)(implicit reporter: Reporter): Response[List[Member]] = { + reporter.println("\naskScopeCompletion at " + pos.source.file.name + ((pos.line, pos.column))) + + ask { + compiler.askScopeCompletion(pos, _) + } + } +} + /** Ask the presentation compiler for type info at a given position. */ trait AskTypeAt extends AskCommand { import compiler.Tree diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala b/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala index c8e6b6ccce..214f7a4553 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala +++ b/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala @@ -13,19 +13,19 @@ private[tests] trait CoreTestDefs /** Ask the presentation compiler for completion at all locations * (in all sources) where the defined `marker` is found. */ - class CompletionAction(override val compiler: Global) + class TypeCompletionAction(override val compiler: Global) extends PresentationCompilerTestDef - with AskCompletionAt { + with AskTypeCompletionAt { def memberPrinter(member: compiler.Member): String = "[accessible: %5s] ".format(member.accessible) + "`" + (member.sym.toString() + member.tpe.toString()).trim() + "`" override def runTest() { - askAllSources(CompletionMarker) { pos => - askCompletionAt(pos) + askAllSources(TypeCompletionMarker) { pos => + askTypeCompletionAt(pos) } { (pos, members) => withResponseDelimiter { - reporter.println("[response] aksTypeCompletion at " + format(pos)) + reporter.println("[response] askTypeCompletion at " + format(pos)) // we skip getClass because it changed signature between 1.5 and 1.6, so there is no // universal check file that we can provide for this to work reporter.println("retrieved %d members".format(members.size)) @@ -38,6 +38,39 @@ private[tests] trait CoreTestDefs } } + /** Ask the presentation compiler for completion at all locations + * (in all sources) where the defined `marker` is found. */ + class ScopeCompletionAction(override val compiler: Global) + extends PresentationCompilerTestDef + with AskScopeCompletionAt { + + def memberPrinter(member: compiler.Member): String = + "[accessible: %5s] ".format(member.accessible) + "`" + (member.sym.toString() + member.tpe.toString()).trim() + "`" + + override def runTest() { + askAllSources(ScopeCompletionMarker) { pos => + askScopeCompletionAt(pos) + } { (pos, members) => + withResponseDelimiter { + reporter.println("[response] askScopeCompletion at " + format(pos)) + try { + // exclude members not from source (don't have position), for more focussed and self contained tests. + def eligible(sym: compiler.Symbol) = sym.pos != compiler.NoPosition + val filtered = members.filter(member => eligible(member.sym)) + reporter.println("retrieved %d members".format(filtered.size)) + compiler ask { () => + reporter.println(filtered.map(memberPrinter).sortBy(_.toString()).mkString("\n")) + } + } catch { + case t: Throwable => + t.printStackTrace() + } + + } + } + } + } + /** Ask the presentation compiler for type info at all locations * (in all sources) where the defined `marker` is found. */ class TypeAction(override val compiler: Global) @@ -61,7 +94,7 @@ private[tests] trait CoreTestDefs class HyperlinkAction(override val compiler: Global) extends PresentationCompilerTestDef with AskTypeAt - with AskCompletionAt { + with AskTypeCompletionAt { override def runTest() { askAllSources(HyperlinkMarker) { pos => @@ -97,4 +130,4 @@ private[tests] trait CoreTestDefs } } } -} \ No newline at end of file +} diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/TestMarker.scala b/src/compiler/scala/tools/nsc/interactive/tests/core/TestMarker.scala index ba1722382b..8698ada4ad 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/core/TestMarker.scala +++ b/src/compiler/scala/tools/nsc/interactive/tests/core/TestMarker.scala @@ -20,7 +20,9 @@ abstract case class TestMarker(val marker: String) { TestMarker.checkForDuplicate(this) } -object CompletionMarker extends TestMarker("/*!*/") +object TypeCompletionMarker extends TestMarker("/*!*/") + +object ScopeCompletionMarker extends TestMarker("/*_*/") object TypeMarker extends TestMarker("/*?*/") diff --git a/test/files/presentation/callcc-interpreter.check b/test/files/presentation/callcc-interpreter.check index 3a08e2a2ea..9a92c40609 100644 --- a/test/files/presentation/callcc-interpreter.check +++ b/test/files/presentation/callcc-interpreter.check @@ -2,7 +2,7 @@ reload: CallccInterpreter.scala askTypeCompletion at CallccInterpreter.scala(51,38) ================================================================================ -[response] aksTypeCompletion at (51,38) +[response] askTypeCompletion at (51,38) retrieved 64 members [accessible: true] `class AddcallccInterpreter.Add` [accessible: true] `class AppcallccInterpreter.App` diff --git a/test/files/presentation/completion-implicit-chained.check b/test/files/presentation/completion-implicit-chained.check index 6d30a61cf9..24417cfa46 100644 --- a/test/files/presentation/completion-implicit-chained.check +++ b/test/files/presentation/completion-implicit-chained.check @@ -2,7 +2,7 @@ reload: Completions.scala askTypeCompletion at Completions.scala(11,16) ================================================================================ -[response] aksTypeCompletion at (11,16) +[response] askTypeCompletion at (11,16) retrieved 24 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` diff --git a/test/files/presentation/ide-bug-1000349.check b/test/files/presentation/ide-bug-1000349.check index 44a3207d75..ada307d0b2 100644 --- a/test/files/presentation/ide-bug-1000349.check +++ b/test/files/presentation/ide-bug-1000349.check @@ -2,7 +2,7 @@ reload: CompletionOnEmptyArgMethod.scala askTypeCompletion at CompletionOnEmptyArgMethod.scala(2,17) ================================================================================ -[response] aksTypeCompletion at (2,17) +[response] askTypeCompletion at (2,17) retrieved 37 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` diff --git a/test/files/presentation/ide-bug-1000475.check b/test/files/presentation/ide-bug-1000475.check index 34c3b557d8..07902727e3 100644 --- a/test/files/presentation/ide-bug-1000475.check +++ b/test/files/presentation/ide-bug-1000475.check @@ -2,7 +2,7 @@ reload: Foo.scala askTypeCompletion at Foo.scala(3,7) ================================================================================ -[response] aksTypeCompletion at (3,7) +[response] askTypeCompletion at (3,7) retrieved 36 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` @@ -40,7 +40,7 @@ retrieved 36 members askTypeCompletion at Foo.scala(6,10) ================================================================================ -[response] aksTypeCompletion at (6,10) +[response] askTypeCompletion at (6,10) retrieved 36 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` @@ -78,7 +78,7 @@ retrieved 36 members askTypeCompletion at Foo.scala(7,7) ================================================================================ -[response] aksTypeCompletion at (7,7) +[response] askTypeCompletion at (7,7) retrieved 36 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` diff --git a/test/files/presentation/ide-bug-1000531.check b/test/files/presentation/ide-bug-1000531.check index 4be98a6b21..a28ecb3437 100644 --- a/test/files/presentation/ide-bug-1000531.check +++ b/test/files/presentation/ide-bug-1000531.check @@ -2,7 +2,7 @@ reload: CrashOnLoad.scala askTypeCompletion at CrashOnLoad.scala(6,12) ================================================================================ -[response] aksTypeCompletion at (6,12) +[response] askTypeCompletion at (6,12) retrieved 126 members [accessible: true] `class GroupedIteratorIterator[B]#GroupedIterator` [accessible: true] `method !=(x$1: Any)Boolean` diff --git a/test/files/presentation/implicit-member.check b/test/files/presentation/implicit-member.check index 05d6f61699..111d06dfa8 100644 --- a/test/files/presentation/implicit-member.check +++ b/test/files/presentation/implicit-member.check @@ -2,7 +2,7 @@ reload: ImplicitMember.scala askTypeCompletion at ImplicitMember.scala(7,7) ================================================================================ -[response] aksTypeCompletion at (7,7) +[response] askTypeCompletion at (7,7) retrieved 39 members [accessible: true] `class AppliedImplicitImplicit.AppliedImplicit` [accessible: true] `method !=(x$1: Any)Boolean` diff --git a/test/files/presentation/ping-pong.check b/test/files/presentation/ping-pong.check index b666d51de5..f714c1b4da 100644 --- a/test/files/presentation/ping-pong.check +++ b/test/files/presentation/ping-pong.check @@ -2,7 +2,7 @@ reload: PingPong.scala askTypeCompletion at PingPong.scala(10,23) ================================================================================ -[response] aksTypeCompletion at (10,23) +[response] askTypeCompletion at (10,23) retrieved 40 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` @@ -43,7 +43,7 @@ retrieved 40 members askTypeCompletion at PingPong.scala(19,20) ================================================================================ -[response] aksTypeCompletion at (19,20) +[response] askTypeCompletion at (19,20) retrieved 40 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` diff --git a/test/files/presentation/t5708.check b/test/files/presentation/t5708.check index c6d4762635..fe43f83cf4 100644 --- a/test/files/presentation/t5708.check +++ b/test/files/presentation/t5708.check @@ -2,7 +2,7 @@ reload: Completions.scala askTypeCompletion at Completions.scala(17,9) ================================================================================ -[response] aksTypeCompletion at (17,9) +[response] askTypeCompletion at (17,9) retrieved 44 members [accessible: true] `lazy value fooInt` [accessible: true] `method !=(x$1: Any)Boolean` diff --git a/test/files/presentation/visibility.check b/test/files/presentation/visibility.check index 3026e58f7e..221e3fc6a0 100644 --- a/test/files/presentation/visibility.check +++ b/test/files/presentation/visibility.check @@ -2,7 +2,7 @@ reload: Completions.scala askTypeCompletion at Completions.scala(14,12) ================================================================================ -[response] aksTypeCompletion at (14,12) +[response] askTypeCompletion at (14,12) retrieved 42 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` @@ -46,7 +46,7 @@ retrieved 42 members askTypeCompletion at Completions.scala(16,11) ================================================================================ -[response] aksTypeCompletion at (16,11) +[response] askTypeCompletion at (16,11) retrieved 42 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` @@ -90,7 +90,7 @@ retrieved 42 members askTypeCompletion at Completions.scala(22,11) ================================================================================ -[response] aksTypeCompletion at (22,11) +[response] askTypeCompletion at (22,11) retrieved 42 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` @@ -134,7 +134,7 @@ retrieved 42 members askTypeCompletion at Completions.scala(28,10) ================================================================================ -[response] aksTypeCompletion at (28,10) +[response] askTypeCompletion at (28,10) retrieved 42 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` @@ -178,7 +178,7 @@ retrieved 42 members askTypeCompletion at Completions.scala(37,8) ================================================================================ -[response] aksTypeCompletion at (37,8) +[response] askTypeCompletion at (37,8) retrieved 42 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` -- cgit v1.2.3 From eb9f0f797535386d44f9bc1f9e0c1765622baa29 Mon Sep 17 00:00:00 2001 From: Luc Bourlier Date: Wed, 13 Nov 2013 15:14:05 +0100 Subject: [nomaster] Adds test cases for scope completion (cherry picked from commit 3d55fe723f1af91f4d2db421f0e0965c583346dc) --- test/files/presentation/scope-completion-1.check | 19 ++ .../presentation/scope-completion-1/Test.scala | 3 + .../scope-completion-1/src/Completions.scala | 12 + test/files/presentation/scope-completion-2.check | 35 +++ .../presentation/scope-completion-2/Test.scala | 3 + .../scope-completion-2/src/Completions.scala | 35 +++ test/files/presentation/scope-completion-3.check | 111 ++++++++ .../presentation/scope-completion-3/Test.scala | 3 + .../scope-completion-3/src/Completions.scala | 106 ++++++++ test/files/presentation/scope-completion-4.check | 293 +++++++++++++++++++++ .../presentation/scope-completion-4/Test.scala | 3 + .../scope-completion-4/src/Completions.scala | 84 ++++++ 12 files changed, 707 insertions(+) create mode 100644 test/files/presentation/scope-completion-1.check create mode 100644 test/files/presentation/scope-completion-1/Test.scala create mode 100644 test/files/presentation/scope-completion-1/src/Completions.scala create mode 100644 test/files/presentation/scope-completion-2.check create mode 100644 test/files/presentation/scope-completion-2/Test.scala create mode 100644 test/files/presentation/scope-completion-2/src/Completions.scala create mode 100644 test/files/presentation/scope-completion-3.check create mode 100644 test/files/presentation/scope-completion-3/Test.scala create mode 100644 test/files/presentation/scope-completion-3/src/Completions.scala create mode 100644 test/files/presentation/scope-completion-4.check create mode 100644 test/files/presentation/scope-completion-4/Test.scala create mode 100644 test/files/presentation/scope-completion-4/src/Completions.scala diff --git a/test/files/presentation/scope-completion-1.check b/test/files/presentation/scope-completion-1.check new file mode 100644 index 0000000000..93c637370d --- /dev/null +++ b/test/files/presentation/scope-completion-1.check @@ -0,0 +1,19 @@ +reload: Completions.scala + +askScopeCompletion at Completions.scala(6,2) +================================================================================ +[response] askScopeCompletion at (6,2) +retrieved 3 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `constructor Completion1()test.Completion1` +[accessible: true] `object Completion2test.Completion2.type` +================================================================================ + +askScopeCompletion at Completions.scala(10,2) +================================================================================ +[response] askScopeCompletion at (10,2) +retrieved 3 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `constructor Completion2()test.Completion2.type` +[accessible: true] `object Completion2test.Completion2.type` +================================================================================ diff --git a/test/files/presentation/scope-completion-1/Test.scala b/test/files/presentation/scope-completion-1/Test.scala new file mode 100644 index 0000000000..bec1131c4c --- /dev/null +++ b/test/files/presentation/scope-completion-1/Test.scala @@ -0,0 +1,3 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest + +object Test extends InteractiveTest \ No newline at end of file diff --git a/test/files/presentation/scope-completion-1/src/Completions.scala b/test/files/presentation/scope-completion-1/src/Completions.scala new file mode 100644 index 0000000000..c4eea6b261 --- /dev/null +++ b/test/files/presentation/scope-completion-1/src/Completions.scala @@ -0,0 +1,12 @@ +package test + +/* completion on empty class and object */ + +class Completion1 { + /*_*/ +} + +object Completion2 { + /*_*/ +} + diff --git a/test/files/presentation/scope-completion-2.check b/test/files/presentation/scope-completion-2.check new file mode 100644 index 0000000000..bd2aa621ff --- /dev/null +++ b/test/files/presentation/scope-completion-2.check @@ -0,0 +1,35 @@ +reload: Completions.scala + +askScopeCompletion at Completions.scala(16,4) +================================================================================ +[response] askScopeCompletion at (16,4) +retrieved 11 members +[accessible: true] `class Cc1Completion1.this.Cc1` +[accessible: true] `class Co1test.Completion1.Co1` +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `constructor Completion1()test.Completion1` +[accessible: true] `method fc1=> Int` +[accessible: true] `method fo1=> Int` +[accessible: true] `method test=> Unit` +[accessible: true] `object Completion1test.Completion1.type` +[accessible: true] `value ctest.Completion1` +[accessible: true] `value vc1Int` +[accessible: true] `value vo1Int` +================================================================================ + +askScopeCompletion at Completions.scala(32,4) +================================================================================ +[response] askScopeCompletion at (32,4) +retrieved 11 members +[accessible: true] `class Cc1test.Completion1.c.Cc1` +[accessible: true] `class Co1test.Completion1.Co1` +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `constructor Completion1()test.Completion1.type` +[accessible: true] `method fc1=> Int` +[accessible: true] `method fo1=> Int` +[accessible: true] `method test=> Unit` +[accessible: true] `object Completion1test.Completion1.type` +[accessible: true] `value ctest.Completion1` +[accessible: true] `value vo1Int` +[accessible: false] `value vc1Int` +================================================================================ diff --git a/test/files/presentation/scope-completion-2/Test.scala b/test/files/presentation/scope-completion-2/Test.scala new file mode 100644 index 0000000000..bec1131c4c --- /dev/null +++ b/test/files/presentation/scope-completion-2/Test.scala @@ -0,0 +1,3 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest + +object Test extends InteractiveTest \ No newline at end of file diff --git a/test/files/presentation/scope-completion-2/src/Completions.scala b/test/files/presentation/scope-completion-2/src/Completions.scala new file mode 100644 index 0000000000..96d38f1b85 --- /dev/null +++ b/test/files/presentation/scope-completion-2/src/Completions.scala @@ -0,0 +1,35 @@ +package test + +/* private elements are visible in the companion class/object */ + +class Completion1 { + + import Completion1._ + + private val vc1 = 0 + private def fc1 = 0 + + private class Cc1 + + def test { + // needs to be done in a method, because of SI-7280 + /*_*/ + } +} + +object Completion1 { + + val c = new Completion1() + import c._ + + private val vo1 = 0 + private def fo1 = 0 + + private class Co1 + + def test { + // needs to be done in a method, because of SI-7280 + /*_*/ + } +} + diff --git a/test/files/presentation/scope-completion-3.check b/test/files/presentation/scope-completion-3.check new file mode 100644 index 0000000000..c48e310355 --- /dev/null +++ b/test/files/presentation/scope-completion-3.check @@ -0,0 +1,111 @@ +reload: Completions.scala + +askScopeCompletion at Completions.scala(75,2) +================================================================================ +[response] askScopeCompletion at (75,2) +retrieved 49 members +[accessible: true] `class Base1test.Base1` +[accessible: true] `class Cb1Completion1.this.Cb1` +[accessible: true] `class Cc1Completion1.this.Cc1` +[accessible: true] `class Cc2Completion1.this.Cc2` +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class Ct1Completion1.this.Ct1` +[accessible: true] `constructor Completion1()test.Completion1` +[accessible: true] `method fb1=> Int` +[accessible: true] `method fb3=> Int` +[accessible: true] `method fc1=> Int` +[accessible: true] `method fc2=> Int` +[accessible: true] `method ft1=> Int` +[accessible: true] `method ft3=> Int` +[accessible: true] `object Completion2test.Completion2.type` +[accessible: true] `object Ob1Completion1.this.Ob1.type` +[accessible: true] `object Oc1Completion1.this.Oc1.type` +[accessible: true] `object Oc2Completion1.this.Oc2.type` +[accessible: true] `object Ot1Completion1.this.Ot1.type` +[accessible: true] `trait Trait1test.Trait1` +[accessible: true] `type tb1Completion1.this.tb1` +[accessible: true] `type tb3Completion1.this.tb3` +[accessible: true] `type tc1Completion1.this.tc1` +[accessible: true] `type tc2Completion1.this.tc2` +[accessible: true] `type tt1Completion1.this.tt1` +[accessible: true] `type tt3Completion1.this.tt3` +[accessible: true] `value vb3Int` +[accessible: true] `value vc1Int` +[accessible: true] `value vc2Int` +[accessible: true] `value vt3Int` +[accessible: true] `variable rb3Int` +[accessible: true] `variable rc1Int` +[accessible: true] `variable rc2Int` +[accessible: true] `variable rt3Int` +[accessible: false] `class Cb2Completion1.this.Cb2` +[accessible: false] `class Ct2Completion1.this.Ct2` +[accessible: false] `method fb2=> Int` +[accessible: false] `method ft2=> Int` +[accessible: false] `object Ob2Completion1.this.Ob2.type` +[accessible: false] `object Ot2Completion1.this.Ot2.type` +[accessible: false] `type tb2Completion1.this.tb2` +[accessible: false] `type tt2Completion1.this.tt2` +[accessible: false] `value vb1Int` +[accessible: false] `value vb2Int` +[accessible: false] `value vt1Int` +[accessible: false] `value vt2Int` +[accessible: false] `variable rb1Int` +[accessible: false] `variable rb2Int` +[accessible: false] `variable rt1Int` +[accessible: false] `variable rt2Int` +================================================================================ + +askScopeCompletion at Completions.scala(104,2) +================================================================================ +[response] askScopeCompletion at (104,2) +retrieved 49 members +[accessible: true] `class Base1test.Base1` +[accessible: true] `class Cb1test.Completion2.Cb1` +[accessible: true] `class Co1test.Completion2.Co1` +[accessible: true] `class Co2test.Completion2.Co2` +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class Ct1test.Completion2.Ct1` +[accessible: true] `constructor Completion2()test.Completion2.type` +[accessible: true] `method fb1=> Int` +[accessible: true] `method fb3=> Int` +[accessible: true] `method fo1=> Int` +[accessible: true] `method fo2=> Int` +[accessible: true] `method ft1=> Int` +[accessible: true] `method ft3=> Int` +[accessible: true] `object Completion2test.Completion2.type` +[accessible: true] `object Ob1test.Completion2.Ob1.type` +[accessible: true] `object Oo1test.Completion2.Oo1.type` +[accessible: true] `object Oo2test.Completion2.Oo2.type` +[accessible: true] `object Ot1test.Completion2.Ot1.type` +[accessible: true] `trait Trait1test.Trait1` +[accessible: true] `type tb1test.Completion2.tb1` +[accessible: true] `type tb3test.Completion2.tb3` +[accessible: true] `type to1test.Completion2.to1` +[accessible: true] `type to2test.Completion2.to2` +[accessible: true] `type tt1test.Completion2.tt1` +[accessible: true] `type tt3test.Completion2.tt3` +[accessible: true] `value vb3Int` +[accessible: true] `value vo1Int` +[accessible: true] `value vo2Int` +[accessible: true] `value vt3Int` +[accessible: true] `variable rb3Int` +[accessible: true] `variable ro1Int` +[accessible: true] `variable ro2Int` +[accessible: true] `variable rt3Int` +[accessible: false] `class Cb2test.Completion2.Cb2` +[accessible: false] `class Ct2test.Completion2.Ct2` +[accessible: false] `method fb2=> Int` +[accessible: false] `method ft2=> Int` +[accessible: false] `object Ob2test.Completion2.Ob2.type` +[accessible: false] `object Ot2test.Completion2.Ot2.type` +[accessible: false] `type tb2test.Completion2.tb2` +[accessible: false] `type tt2test.Completion2.tt2` +[accessible: false] `value vb1Int` +[accessible: false] `value vb2Int` +[accessible: false] `value vt1Int` +[accessible: false] `value vt2Int` +[accessible: false] `variable rb1Int` +[accessible: false] `variable rb2Int` +[accessible: false] `variable rt1Int` +[accessible: false] `variable rt2Int` +================================================================================ diff --git a/test/files/presentation/scope-completion-3/Test.scala b/test/files/presentation/scope-completion-3/Test.scala new file mode 100644 index 0000000000..bec1131c4c --- /dev/null +++ b/test/files/presentation/scope-completion-3/Test.scala @@ -0,0 +1,3 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest + +object Test extends InteractiveTest \ No newline at end of file diff --git a/test/files/presentation/scope-completion-3/src/Completions.scala b/test/files/presentation/scope-completion-3/src/Completions.scala new file mode 100644 index 0000000000..18cef1cefa --- /dev/null +++ b/test/files/presentation/scope-completion-3/src/Completions.scala @@ -0,0 +1,106 @@ +package test + +/* check availability of members defined locally and in hierachy */ + +abstract class Base1 { + + type tb1 = Int + val vb1 = 0 + var rb1 = 0 + def fb1 = 0 + class Cb1 + object Ob1 + + private type tb2 = Int + private val vb2 = 0 + private var rb2 = 0 + private def fb2 = 0 + private class Cb2 + private object Ob2 + + type tb3 + val vb3: Int + var rb3: Int + def fb3: Int +} + +trait Trait1 { + + type tt1 = Int + val vt1 = 0 + var rt1 = 0 + def ft1 = 0 + class Ct1 + object Ot1 + + private type tt2 = Int + private val vt2 = 0 + private var rt2 = 0 + private def ft2 = 0 + private class Ct2 + private object Ot2 + + type tt3 + val vt3: Int + var rt3: Int + def ft3: Int +} + +class Completion1 extends Base1 with Trait1 { + + type tc1 = Int + val vc1 = 0 + var rc1 = 0 + def fc1 = 0 + class Cc1 + object Oc1 + + private type tc2 = Int + private val vc2 = 0 + private var rc2 = 0 + private def fc2 = 0 + private class Cc2 + private object Oc2 + + override type tb3 = Int + override val vb3 = 12 + override var rb3 = 12 + override def fb3 = 12 + + override type tt3 = Int + override val vt3 = 12 + override var rt3 = 12 + override def ft3 = 12 + + /*_*/ +} + +object Completion2 extends Base1 with Trait1 { + + type to1 = Int + val vo1 = 0 + var ro1 = 0 + def fo1 = 0 + class Co1 + object Oo1 + + private type to2 = Int + private val vo2 = 0 + private var ro2 = 0 + private def fo2 = 0 + private class Co2 + private object Oo2 + + override type tb3 = Int + override val vb3 = 12 + override var rb3 = 12 + override def fb3 = 12 + + override type tt3 = Int + override val vt3 = 12 + override var rt3 = 12 + override def ft3 = 12 + + /*_*/ +} + diff --git a/test/files/presentation/scope-completion-4.check b/test/files/presentation/scope-completion-4.check new file mode 100644 index 0000000000..f6241cf7f7 --- /dev/null +++ b/test/files/presentation/scope-completion-4.check @@ -0,0 +1,293 @@ +reload: Completions.scala + +askScopeCompletion at Completions.scala(12,8) +================================================================================ +[response] askScopeCompletion at (12,8) +retrieved 8 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `class fcfc` +[accessible: true] `class ffcffc` +[accessible: true] `constructor Completion1()test.Completion1` +[accessible: true] `method f=> Unit` +[accessible: true] `method ff=> Unit` +[accessible: true] `method fff=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(15,6) +================================================================================ +[response] askScopeCompletion at (15,6) +retrieved 8 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `class fcfc` +[accessible: true] `class ffcffc` +[accessible: true] `constructor Completion1()test.Completion1` +[accessible: true] `method f=> Unit` +[accessible: true] `method ff=> Unit` +[accessible: true] `method fff=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(18,8) +================================================================================ +[response] askScopeCompletion at (18,8) +retrieved 8 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `class fcfc` +[accessible: true] `class ffcffc` +[accessible: true] `constructor ffc()ffc` +[accessible: true] `method f=> Unit` +[accessible: true] `method ff=> Unit` +[accessible: true] `method fff=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(21,6) +================================================================================ +[response] askScopeCompletion at (21,6) +retrieved 8 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `class fcfc` +[accessible: true] `class ffcffc` +[accessible: true] `constructor Completion1()test.Completion1` +[accessible: true] `method f=> Unit` +[accessible: true] `method ff=> Unit` +[accessible: true] `method fff=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(24,4) +================================================================================ +[response] askScopeCompletion at (24,4) +retrieved 6 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `class fcfc` +[accessible: true] `constructor Completion1()test.Completion1` +[accessible: true] `method f=> Unit` +[accessible: true] `method ff=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(29,8) +================================================================================ +[response] askScopeCompletion at (29,8) +retrieved 8 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `class fccfc.this.fcc` +[accessible: true] `class fcfc` +[accessible: true] `constructor fc()fc` +[accessible: true] `method f=> Unit` +[accessible: true] `method fcf=> Unit` +[accessible: true] `method ff=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(32,6) +================================================================================ +[response] askScopeCompletion at (32,6) +retrieved 8 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `class fccfc.this.fcc` +[accessible: true] `class fcfc` +[accessible: true] `constructor fc()fc` +[accessible: true] `method f=> Unit` +[accessible: true] `method fcf=> Unit` +[accessible: true] `method ff=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(35,8) +================================================================================ +[response] askScopeCompletion at (35,8) +retrieved 8 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `class fccfc.this.fcc` +[accessible: true] `class fcfc` +[accessible: true] `constructor fcc()fc.this.fcc` +[accessible: true] `method f=> Unit` +[accessible: true] `method fcf=> Unit` +[accessible: true] `method ff=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(38,6) +================================================================================ +[response] askScopeCompletion at (38,6) +retrieved 8 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `class fccfc.this.fcc` +[accessible: true] `class fcfc` +[accessible: true] `constructor fc()fc` +[accessible: true] `method f=> Unit` +[accessible: true] `method fcf=> Unit` +[accessible: true] `method ff=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(41,4) +================================================================================ +[response] askScopeCompletion at (41,4) +retrieved 6 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `class fcfc` +[accessible: true] `constructor Completion1()test.Completion1` +[accessible: true] `method f=> Unit` +[accessible: true] `method ff=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(44,2) +================================================================================ +[response] askScopeCompletion at (44,2) +retrieved 4 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `constructor Completion1()test.Completion1` +[accessible: true] `method f=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(51,8) +================================================================================ +[response] askScopeCompletion at (51,8) +retrieved 8 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `class ccc.this.cc` +[accessible: true] `class ccccc.this.ccc` +[accessible: true] `constructor ccc()cc.this.ccc` +[accessible: true] `method ccf=> Unit` +[accessible: true] `method cf=> Unit` +[accessible: true] `method f=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(54,6) +================================================================================ +[response] askScopeCompletion at (54,6) +retrieved 8 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `class ccc.this.cc` +[accessible: true] `class ccccc.this.ccc` +[accessible: true] `constructor cc()c.this.cc` +[accessible: true] `method ccf=> Unit` +[accessible: true] `method cf=> Unit` +[accessible: true] `method f=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(57,8) +================================================================================ +[response] askScopeCompletion at (57,8) +retrieved 8 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `class ccc.this.cc` +[accessible: true] `class ccccc.this.ccc` +[accessible: true] `constructor cc()c.this.cc` +[accessible: true] `method ccf=> Unit` +[accessible: true] `method cf=> Unit` +[accessible: true] `method f=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(60,6) +================================================================================ +[response] askScopeCompletion at (60,6) +retrieved 8 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `class ccc.this.cc` +[accessible: true] `class ccccc.this.ccc` +[accessible: true] `constructor cc()c.this.cc` +[accessible: true] `method ccf=> Unit` +[accessible: true] `method cf=> Unit` +[accessible: true] `method f=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(63,4) +================================================================================ +[response] askScopeCompletion at (63,4) +retrieved 6 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `class ccc.this.cc` +[accessible: true] `constructor c()Completion1.this.c` +[accessible: true] `method cf=> Unit` +[accessible: true] `method f=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(68,8) +================================================================================ +[response] askScopeCompletion at (68,8) +retrieved 8 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `class ccc.this.cc` +[accessible: true] `class cfccfc` +[accessible: true] `constructor cfc()cfc` +[accessible: true] `method cf=> Unit` +[accessible: true] `method cff=> Unit` +[accessible: true] `method f=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(71,6) +================================================================================ +[response] askScopeCompletion at (71,6) +retrieved 8 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `class ccc.this.cc` +[accessible: true] `class cfccfc` +[accessible: true] `constructor c()Completion1.this.c` +[accessible: true] `method cf=> Unit` +[accessible: true] `method cff=> Unit` +[accessible: true] `method f=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(74,8) +================================================================================ +[response] askScopeCompletion at (74,8) +retrieved 8 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `class ccc.this.cc` +[accessible: true] `class cfccfc` +[accessible: true] `constructor c()Completion1.this.c` +[accessible: true] `method cf=> Unit` +[accessible: true] `method cff=> Unit` +[accessible: true] `method f=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(77,6) +================================================================================ +[response] askScopeCompletion at (77,6) +retrieved 8 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `class ccc.this.cc` +[accessible: true] `class cfccfc` +[accessible: true] `constructor c()Completion1.this.c` +[accessible: true] `method cf=> Unit` +[accessible: true] `method cff=> Unit` +[accessible: true] `method f=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(80,4) +================================================================================ +[response] askScopeCompletion at (80,4) +retrieved 6 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `class ccc.this.cc` +[accessible: true] `constructor c()Completion1.this.c` +[accessible: true] `method cf=> Unit` +[accessible: true] `method f=> Unit` +================================================================================ + +askScopeCompletion at Completions.scala(83,2) +================================================================================ +[response] askScopeCompletion at (83,2) +retrieved 4 members +[accessible: true] `class Completion1test.Completion1` +[accessible: true] `class cCompletion1.this.c` +[accessible: true] `constructor Completion1()test.Completion1` +[accessible: true] `method f=> Unit` +================================================================================ diff --git a/test/files/presentation/scope-completion-4/Test.scala b/test/files/presentation/scope-completion-4/Test.scala new file mode 100644 index 0000000000..bec1131c4c --- /dev/null +++ b/test/files/presentation/scope-completion-4/Test.scala @@ -0,0 +1,3 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest + +object Test extends InteractiveTest \ No newline at end of file diff --git a/test/files/presentation/scope-completion-4/src/Completions.scala b/test/files/presentation/scope-completion-4/src/Completions.scala new file mode 100644 index 0000000000..d11315720a --- /dev/null +++ b/test/files/presentation/scope-completion-4/src/Completions.scala @@ -0,0 +1,84 @@ +package test + +/* check that members defined in sub-block are not visible*/ + +class Completion1 { + + def f { + + def ff { + + def fff { + /*_*/ + } + + /*_*/ + + class ffc { + /*_*/ + } + + /*_*/ + } + + /*_*/ + + class fc { + + def fcf { + /*_*/ + } + + /*_*/ + + class fcc { + /*_*/ + } + + /*_*/ + } + + /*_*/ + } + + /*_*/ + + class c { + + class cc { + + class ccc { + /*_*/ + } + + /*_*/ + + def ccf { + /*_*/ + } + + /*_*/ + } + + /*_*/ + + def cf { + + class cfc { + /*_*/ + } + + /*_*/ + + def cff { + /*_*/ + } + + /*_*/ + } + + /*_*/ + } + + /*_*/ +} -- cgit v1.2.3 From 053a2744c6dfa339e004fbdab8994dc435e60b45 Mon Sep 17 00:00:00 2001 From: Luc Bourlier Date: Wed, 13 Nov 2013 17:24:59 +0100 Subject: [nomaster] SI-7280 Scope completion not returning members provided by imports Updates localeContext() to return the best context possible when there are none directly associated with the given position. It happens when an expression cannot be successfully typed, as no precise ContextTree covers the expression location, or if the position is not inside any expression. Adds corresponding tests (cherry picked from commit 3028327e2a2b553b12ee45519413515c8aa0865f) --- .../scala/tools/nsc/interactive/ContextTrees.scala | 65 ++++++---- .../presentation/scope-completion-import.check | 141 +++++++++++++++++++++ .../scope-completion-import/Test.scala | 3 + .../scope-completion-import/src/Completions.scala | 64 ++++++++++ 4 files changed, 248 insertions(+), 25 deletions(-) create mode 100644 test/files/presentation/scope-completion-import.check create mode 100644 test/files/presentation/scope-completion-import/Test.scala create mode 100644 test/files/presentation/scope-completion-import/src/Completions.scala diff --git a/src/compiler/scala/tools/nsc/interactive/ContextTrees.scala b/src/compiler/scala/tools/nsc/interactive/ContextTrees.scala index b2568e34bd..4a61a98921 100644 --- a/src/compiler/scala/tools/nsc/interactive/ContextTrees.scala +++ b/src/compiler/scala/tools/nsc/interactive/ContextTrees.scala @@ -6,7 +6,7 @@ package scala.tools.nsc package interactive import scala.collection.mutable.ArrayBuffer -import scala.reflect.internal.util.Position +import scala.annotation.tailrec trait ContextTrees { self: Global => @@ -29,44 +29,59 @@ trait ContextTrees { self: Global => override def toString = "ContextTree("+pos+", "+children+")" } - /** Optionally returns the smallest context that contains given `pos`, or None if none exists. + /** Returns the most precise context possible for the given `pos`. + * + * It looks for the finest ContextTree containing `pos`, and then look inside + * this ContextTree for a child ContextTree located immediately before `pos`. + * If such a child exists, returns its context, otherwise returns the context of + * the parent ContextTree. + * + * This is required to always return a context which contains the all the imports + * declared up to `pos` (see SI-7280 for a test case). + * + * Can return None if `pos` is before any valid Scala code. */ def locateContext(contexts: Contexts, pos: Position): Option[Context] = synchronized { - def locateNearestContextTree(contexts: Contexts, pos: Position, recent: Array[ContextTree]): Option[ContextTree] = { - locateContextTree(contexts, pos) match { - case Some(x) => - recent(0) = x - locateNearestContextTree(x.children, pos, recent) - case None => recent(0) match { - case null => None - case x => Some(x) - } + @tailrec + def locateFinestContextTree(context: ContextTree): ContextTree = { + if (context.pos includes pos) { + locateContextTree(context.children, pos) match { + case Some(x) => + locateFinestContextTree(x) + case None => + context + } + } else { + context } } - locateNearestContextTree(contexts, pos, new Array[ContextTree](1)) map (_.context) + locateContextTree(contexts, pos) map locateFinestContextTree map (_.context) } + /** Returns the ContextTree containing `pos`, or the ContextTree positioned just before `pos`, + * or None if `pos` is located before all ContextTrees. + */ def locateContextTree(contexts: Contexts, pos: Position): Option[ContextTree] = { if (contexts.isEmpty) None else { - val hi = contexts.length - 1 - if ((contexts(hi).pos properlyPrecedes pos) || (pos properlyPrecedes contexts(0).pos)) None - else { - def loop(lo: Int, hi: Int): Option[ContextTree] = { + @tailrec + def loop(lo: Int, hi: Int, previousSibling: Option[ContextTree]): Option[ContextTree] = { + if (pos properlyPrecedes contexts(lo).pos) + previousSibling + else if (contexts(hi).pos properlyPrecedes pos) + Some(contexts(hi)) + else { val mid = (lo + hi) / 2 val midpos = contexts(mid).pos - if ((pos precedes midpos) && (mid < hi)) - loop(lo, mid) - else if ((midpos precedes pos) && (lo < mid)) - loop(mid, hi) - else if (midpos includes pos) + if (midpos includes pos) Some(contexts(mid)) - else if (contexts(mid+1).pos includes pos) - Some(contexts(mid+1)) - else None + else if (midpos properlyPrecedes pos) + loop(mid + 1, hi, Some(contexts(mid))) + else + loop(lo, mid, previousSibling) } - loop(0, hi) } + loop(0, contexts.length - 1, None) } } diff --git a/test/files/presentation/scope-completion-import.check b/test/files/presentation/scope-completion-import.check new file mode 100644 index 0000000000..1d84abd617 --- /dev/null +++ b/test/files/presentation/scope-completion-import.check @@ -0,0 +1,141 @@ +reload: Completions.scala + +askScopeCompletion at Completions.scala(15,4) +================================================================================ +[response] askScopeCompletion at (15,4) +retrieved 10 members +[accessible: true] `class Ctest.C` +[accessible: true] `class Foo_1test.Foo_1` +[accessible: true] `class Foo_2test.Foo_2` +[accessible: true] `class Foo_3test.Foo_3` +[accessible: true] `class Footest.Foo` +[accessible: true] `constructor Foo()test.Foo` +[accessible: true] `method fCCC=> Int` +[accessible: true] `method fOOO=> Int` +[accessible: true] `object Otest.O.type` +[accessible: true] `value otest.O.type` +================================================================================ + +askScopeCompletion at Completions.scala(19,4) +================================================================================ +[response] askScopeCompletion at (19,4) +retrieved 9 members +[accessible: true] `class Ctest.C` +[accessible: true] `class Foo_1test.Foo_1` +[accessible: true] `class Foo_2test.Foo_2` +[accessible: true] `class Foo_3test.Foo_3` +[accessible: true] `class Footest.Foo` +[accessible: true] `constructor Foo()test.Foo` +[accessible: true] `method fCCC=> Int` +[accessible: true] `method fOOO=> Int` +[accessible: true] `object Otest.O.type` +================================================================================ + +askScopeCompletion at Completions.scala(24,4) +================================================================================ +[response] askScopeCompletion at (24,4) +retrieved 9 members +[accessible: true] `class Ctest.C` +[accessible: true] `class Foo_1test.Foo_1` +[accessible: true] `class Foo_2test.Foo_2` +[accessible: true] `class Foo_3test.Foo_3` +[accessible: true] `class Footest.Foo` +[accessible: true] `constructor Foo()test.Foo` +[accessible: true] `method fCCC=> Int` +[accessible: true] `object Otest.O.type` +[accessible: true] `value ctest.C` +================================================================================ + +askScopeCompletion at Completions.scala(27,5) +================================================================================ +[response] askScopeCompletion at (27,5) +retrieved 8 members +[accessible: true] `class Ctest.C` +[accessible: true] `class Foo_1test.Foo_1` +[accessible: true] `class Foo_2test.Foo_2` +[accessible: true] `class Foo_3test.Foo_3` +[accessible: true] `class Footest.Foo` +[accessible: true] `constructor Foo()test.Foo` +[accessible: true] `object Otest.O.type` +[accessible: true] `value ctest.C` +================================================================================ + +askScopeCompletion at Completions.scala(30,5) +================================================================================ +[response] askScopeCompletion at (30,5) +retrieved 9 members +[accessible: true] `class Ctest.C` +[accessible: true] `class Foo_1test.Foo_1` +[accessible: true] `class Foo_2test.Foo_2` +[accessible: true] `class Foo_3test.Foo_3` +[accessible: true] `class Footest.Foo` +[accessible: true] `constructor Foo()test.Foo` +[accessible: true] `method fCCC=> Int` +[accessible: true] `object Otest.O.type` +[accessible: true] `value ctest.C` +================================================================================ + +askScopeCompletion at Completions.scala(32,5) +================================================================================ +[response] askScopeCompletion at (32,5) +retrieved 10 members +[accessible: true] `class Ctest.C` +[accessible: true] `class Foo_1test.Foo_1` +[accessible: true] `class Foo_2test.Foo_2` +[accessible: true] `class Foo_3test.Foo_3` +[accessible: true] `class Footest.Foo` +[accessible: true] `constructor Foo()test.Foo` +[accessible: true] `method fCCC=> Int` +[accessible: true] `method fOOO=> Int` +[accessible: true] `object Otest.O.type` +[accessible: true] `value ctest.C` +================================================================================ + +askScopeCompletion at Completions.scala(41,4) +================================================================================ +[response] askScopeCompletion at (41,4) +retrieved 10 members +[accessible: true] `class Ctest.C` +[accessible: true] `class Foo_1test.Foo_1` +[accessible: true] `class Foo_2test.Foo_2` +[accessible: true] `class Foo_3test.Foo_3` +[accessible: true] `class Footest.Foo` +[accessible: true] `constructor Foo_1()test.Foo_1` +[accessible: true] `method bar=> Unit` +[accessible: true] `method fCCC=> Int` +[accessible: true] `method fOOO=> Int` +[accessible: true] `object Otest.O.type` +================================================================================ + +askScopeCompletion at Completions.scala(51,4) +================================================================================ +[response] askScopeCompletion at (51,4) +retrieved 11 members +[accessible: true] `class Ctest.C` +[accessible: true] `class Foo_1test.Foo_1` +[accessible: true] `class Foo_2test.Foo_2` +[accessible: true] `class Foo_3test.Foo_3` +[accessible: true] `class Footest.Foo` +[accessible: true] `constructor Foo_2()test.Foo_2` +[accessible: true] `method bar=> Unit` +[accessible: true] `method fCCC=> Int` +[accessible: true] `method fOOO=> Int` +[accessible: true] `object Otest.O.type` +[accessible: true] `value otest.O.type` +================================================================================ + +askScopeCompletion at Completions.scala(61,4) +================================================================================ +[response] askScopeCompletion at (61,4) +retrieved 10 members +[accessible: true] `class Ctest.C` +[accessible: true] `class Foo_1test.Foo_1` +[accessible: true] `class Foo_2test.Foo_2` +[accessible: true] `class Foo_3test.Foo_3` +[accessible: true] `class Footest.Foo` +[accessible: true] `constructor Foo_3()test.Foo_3` +[accessible: true] `method bar=> Unit` +[accessible: true] `method fCCC=> Int` +[accessible: true] `object Otest.O.type` +[accessible: true] `value ctest.C` +================================================================================ diff --git a/test/files/presentation/scope-completion-import/Test.scala b/test/files/presentation/scope-completion-import/Test.scala new file mode 100644 index 0000000000..bec1131c4c --- /dev/null +++ b/test/files/presentation/scope-completion-import/Test.scala @@ -0,0 +1,3 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest + +object Test extends InteractiveTest \ No newline at end of file diff --git a/test/files/presentation/scope-completion-import/src/Completions.scala b/test/files/presentation/scope-completion-import/src/Completions.scala new file mode 100644 index 0000000000..6e08321283 --- /dev/null +++ b/test/files/presentation/scope-completion-import/src/Completions.scala @@ -0,0 +1,64 @@ +package test + +class C { + def fCCC : Int = 0 +} + +object O extends C { + def fOOO : Int = 0 +} + +class Foo { + { + val o = O + import o._ + /*_*/ + } + { + import O._ + /*_*/ + } + { + val c = new C + import c._ + /*_*/ + } + { + f/*_*/ + val c = new C + import c._ + f/*_*/ + import O._ + f/*_*/ + } +} + +class Foo_1 { + + import O._ + + def bar { + /*_*/ + } +} + +class Foo_2 { + + val o = O + import o._ + + def bar { + /*_*/ + } +} + +class Foo_3 { + + val c = new C + import c._ + + def bar { + /*_*/ + } +} + -- cgit v1.2.3