summaryrefslogtreecommitdiff
path: root/test/files/presentation/visibility.check
Commit message (Collapse)AuthorAgeFilesLines
* SI-7475 Private members are not inheritableJason Zaugg2014-02-101-2/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | It turns out `findMembers` has been a bit sloppy in recent years and has returned private members from *anywhere* up the base class sequence. Access checks usually pick up the slack and eliminate the unwanted privates. But, in concert with the "concrete beats abstract" rule in `findMember`, the following mishap appeared: scala> :paste // Entering paste mode (ctrl-D to finish) trait T { def a: Int } trait B { private def a: Int = 0 } trait C extends T with B { a } // Exiting paste mode, now interpreting. <console>:9: error: method a in trait B cannot be accessed in C trait C extends T with B { a } ^ I noticed this when compiling Akka against JDK 8; a new private method in the bowels of the JDK was enough to break the build! It turns out that some finesse in needed to interpret SLS 5.2: > The private modifier can be used with any definition or declaration > in a template. They are not inherited by subclasses [...] So, can we simply exclude privates from all but the first base class? No, as that might be a refinement class! The following must be allowed: trait A { private def foo = 0; trait T { self: A => this.foo } } This commit: - tracks when the walk up the base class sequence passes the first non-refinement class, and excludes private members - ... except, if we are at a direct parent of a refinement class itself - Makes a corresponding change to OverridingPairs, to only consider private members if they are owned by the `base` Symbol under consideration. We don't need to deal with the subtleties of refinements there as that code is only used for bona-fide classes. - replaces use of `hasTransOwner` when considering whether a private[this] symbol is a member. The last condition was not grounded in the spec at all. The change is visible in cases like: // Old scala> trait A { private[this] val x = 0; class B extends A { this.x } } <console>:7: error: value x in trait A cannot be accessed in A.this.B trait A { private[this] val x = 0; class B extends A { this.x } } ^ // New scala> trait A { private[this] val x = 0; class B extends A { this.x } } <console>:8: error: value x is not a member of A.this.B trait A { private[this] val x = 0; class B extends A { this.x } } ^ Furthermore, we no longer give a `private[this]` member a free pass if it is sourced from the very first base class. trait Cake extends Slice { private[this] val bippy = () } trait Slice { self: Cake => bippy // BCS: Cake, Slice, AnyRef, Any } The different handling between `private` and `private[this]` still seems a bit dubious. The spec says: > An different form of qualification is private[this]. A member M > marked with this modifier can be accessed only from within the > object in which it is defined. That is, a selection p.M is only > legal if the prefix is this or O.this, for some class O enclosing > the reference. In addition, the restrictions for unqualified > private apply. This sounds like a question of access, not membership. If so, we should admit `private[this]` members from parents of refined types in `FindMember`. AFAICT, not too much rests on the distinction: do we get a "no such member", or "member foo inaccessible" error? I welcome scrutinee of the checkfile of `neg/t7475f.scala` to help put this last piece into the puzzle. One more thing: findMember does not have *any* code the corresponds to the last sentence of: > SLS 5.2 The modifier can be qualified with an identifier C > (e.g. private[C]) that must denote a class or package enclosing > the definition. Members labeled with such a modifier are accessible > respectively only from code inside the package C or only from code > inside the class C and its companion module (ยง5.4). > Such members are also inherited only from templates inside C. When I showed Martin this, he suggested it was an error in the spec, and we should leave the access checking to callers of that inherited qualified-private member.
* SI-8129 Make Object#== override Any#==Jason Zaugg2014-02-101-15/+5
| | | | | | | | | | | | | | | | | | | | And the same for != If we tried to declare these signatures in non-fictional classes, we would be chastised about collapsing into the "same signature after erasure". This will have an influence of typing, as the typechecking of arguments is sensitive to overloading: if multiple variants are feasible, the argument will be typechecked with a wildcard expected type. So people inspecting the types of the arguments to `==` before this change might have seen an interesting type for `if (true) x else y`, but now the `If` will have type `Any`, as we don't need to calculate the LUB. I've left a TODO to note that we should really make `Any#{==, !=}` non-final and include a final override in `AnyVal`. But I don't think that is particularly urgent.
* Test infrastructure for scope completionJason Zaugg2013-11-151-5/+5
| | | | | Adds a new marker /*_*/ to trigger scope completion test. Original type completion test oracles update for the tweaked output
* Make parameters to implicit value classes privateJason Zaugg2013-11-121-25/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | So that they aren't offered as an autocomplete suggestion: implicit class Shouty(string: String) extends AnyVal { def SHOUT_! = string.toUpperCase + "!" } "". // autocompletion offers `.string` here The original incarnation of value classes didn't allow this sort of encapsulation, so we either invented goofy names like `__thingToAdd` or just picked `x` or `self`. But SI-7859 has delivered us the freedom to keep the accessor private. Should we keep any of these accessors around in a deprecated form? The implicit classes in Predef were added in 2.11.0-M2 (c26a8db067e4f), so they are okay. I think we can make reason that these APIs were both accidental and unlikely to be interpreted as public, so we can break them immediately. scala> Left(1).x res0: scala.util.Either[Int,Int] = Left(1) scala> import concurrent.duration._ import concurrent.duration._ scala> 1.n res1: Int = 1
* More useful checkfile output in interactive tests.Paul Phillips2013-04-301-195/+195
| | | | | | I resisted the urge to fix "aksTypeCompletion" for as long as I possibly could. While I was there I threw in what seem to be like significant output improvements, but you tell me.
* Maintenance of Predef.Paul Phillips2013-02-121-5/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1) Deprecates much of Predef and scala.Console, especially: - the read* methods (see below) - the set{Out,Err,In} methods (see SI-4793) 2) Removed long-deprecated: - Predef#exit - Predef#error should have gone, but could not due to sbt At least the whole source base has now been future-proofed against the eventual removal of Predef#error. The low justification for the read* methods should be readily apparent: they are little used and have no call to be in global namespace, especially given their weird ad hoc semantics and unreasonably tempting names such as readBoolean(). 3) Segregated the deprecated elements in Predef from the part which still thrives. 4) Converted all the standard Predef implicits into implicit classes, value classes where possible: - ArrowAssoc, Ensuring, StringFormat, StringAdd, RichException (value) - SeqCharSequence, ArrayCharSequence (non-value) Non-implicit deprecated stubs prop up the names of the formerly converting methods.
* SI-6811 Remove primitive widenings and /:\Simon Ochsenreither2013-01-171-10/+5
|
* A whole bunch of checkfile updates.Paul Phillips2012-05-101-15/+15
| | | | | Wasn't me this time (I don't think!) Mr. Robot can't get here too soon for me.
* Presentation Compiler tests for visibility of members.Iulian Dragos2012-04-301-0/+221
Removed some unneeded indirection in the testing framework.