diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2014-01-27 15:19:07 +0300 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2014-02-12 14:50:17 +0100 |
commit | 7c06c9d7f6a12c2b13c83b195fffa30c5a4ec3ce (patch) | |
tree | 6b99b01a0de8330174afef9ae615651e7ffcecc8 | |
parent | 30174f9453a44845156f4abca0cd6317da3e27cc (diff) | |
download | scala-7c06c9d7f6a12c2b13c83b195fffa30c5a4ec3ce.tar.gz scala-7c06c9d7f6a12c2b13c83b195fffa30c5a4ec3ce.tar.bz2 scala-7c06c9d7f6a12c2b13c83b195fffa30c5a4ec3ce.zip |
SI-6733 LOCAL, isLocal, and private[this]
Due to an unfortunate name collision, internal.Symbols#Symbol.isLocal
means something different from Flag.LOCAL. Therefore api.Symbols#Symbol.isLocal
was directly violating its documentation.
Since we can’t give api#isLocal an implementation different from internal#isLocal,
we have to rename, and for that occasion I have come up with names
api#isPrivateThis and api#isProtectedThis, which in my opinion suits the
public API better than internal#isPrivateLocal and internal#isProtectedLocal.
Given the extraordinary circumstances of having no way for api#isLocal
to work correctly, I’m forced to remove api#isLocal without a deprecation
notice, exercising our right to break experimental APIs, something that
we have never done before for reflection or macros. This is sad.
-rw-r--r-- | src/reflect/scala/reflect/api/FlagSets.scala | 4 | ||||
-rw-r--r-- | src/reflect/scala/reflect/api/Symbols.scala | 21 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Symbols.scala | 2 | ||||
-rw-r--r-- | test/files/run/t6733.check | 27 | ||||
-rw-r--r-- | test/files/run/t6733.scala | 35 |
5 files changed, 79 insertions, 10 deletions
diff --git a/src/reflect/scala/reflect/api/FlagSets.scala b/src/reflect/scala/reflect/api/FlagSets.scala index 44c5f78a48..f36056cc3b 100644 --- a/src/reflect/scala/reflect/api/FlagSets.scala +++ b/src/reflect/scala/reflect/api/FlagSets.scala @@ -131,8 +131,8 @@ trait FlagSets { self: Universe => /** Flag indicating that tree has `protected` modifier set */ val PROTECTED: FlagSet - /** Flag indicating that tree represents a member local to current class - * (i.e. private[this] or protected[this]. + /** Flag indicating that tree represents a member local to current class, + * i.e. private[this] or protected[this]. * This requires having either PRIVATE or PROTECTED set as well. */ val LOCAL: FlagSet diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala index 1c3ae77d45..15d4fae59b 100644 --- a/src/reflect/scala/reflect/api/Symbols.scala +++ b/src/reflect/scala/reflect/api/Symbols.scala @@ -380,16 +380,13 @@ trait Symbols { self: Universe => */ def isImplementationArtifact: Boolean - /** Does this symbol represent a local declaration or definition? - * - * If yes, either `isPrivate` or `isProtected` are guaranteed to be true. - * Local symbols can only be accessed from the same object instance. - * - * If yes, `privateWithin` might tell more about this symbol's visibility scope. + /** Does this symbol represent a declaration or definition written in a source file as `private[this]` + * or generated in tree/symbol form with the combination of flags LOCAL and PRIVATE? + * If yes, `isPrivate` is guaranteed to be true, * * @group Tests */ - def isLocal: Boolean + def isPrivateThis: Boolean /** Does this symbol represent a private declaration or definition? * If yes, `privateWithin` might tell more about this symbol's visibility scope. @@ -398,6 +395,14 @@ trait Symbols { self: Universe => */ def isPrivate: Boolean + /** Does this symbol represent a declaration or definition written in a source file as `protected[this]` + * or generated in tree/symbol form with the combination of flags LOCAL and PROTECTED? + * If yes, `isProtected` is guaranteed to be true, + * + * @group Tests + */ + def isProtectedThis: Boolean + /** Does this symbol represent a protected declaration or definition? * If yes, `privateWithin` might tell more about this symbol's visibility scope. * @@ -412,7 +417,7 @@ trait Symbols { self: Universe => def isPublic: Boolean /** - * Set when symbol has a modifier of the form private[X], NoSymbol otherwise. + * Set when symbol has a modifier of the form private[X] or protected[X], NoSymbol otherwise. * * Access level encoding: there are three scala flags (PRIVATE, PROTECTED, * and LOCAL) which combine with value privateWithin (the "foo" in private[foo]) diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 593c5e314a..6fedb74f86 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -90,6 +90,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => def isVal: Boolean = isTerm && !isModule && !isMethod && !isMutable def isVar: Boolean = isTerm && !isModule && !isMethod && !isLazy && isMutable def isAbstract: Boolean = isAbstractClass || isDeferred || isAbstractType + def isPrivateThis = (this hasFlag PRIVATE) && (this hasFlag LOCAL) + def isProtectedThis = (this hasFlag PROTECTED) && (this hasFlag LOCAL) def newNestedSymbol(name: Name, pos: Position, newFlags: Long, isClass: Boolean): Symbol = name match { case n: TermName => newTermSymbol(n, pos, newFlags) diff --git a/test/files/run/t6733.check b/test/files/run/t6733.check new file mode 100644 index 0000000000..aeb595fbfd --- /dev/null +++ b/test/files/run/t6733.check @@ -0,0 +1,27 @@ +method $init$: isPrivateThis = false, isProtectedThis = false +value pri1a: isPrivateThis = true, isProtectedThis = false +method pri2a: isPrivateThis = true, isProtectedThis = false +variable pri3a: isPrivateThis = true, isProtectedThis = false +value pri4a: isPrivateThis = true, isProtectedThis = false +lazy value pri4a: isPrivateThis = true, isProtectedThis = false +type Pri5a: isPrivateThis = true, isProtectedThis = false +class Pri6: isPrivateThis = true, isProtectedThis = false +trait Pri7: isPrivateThis = true, isProtectedThis = false +object Pri8: isPrivateThis = true, isProtectedThis = false +value pro1a: isPrivateThis = false, isProtectedThis = true +value pro1a: isPrivateThis = true, isProtectedThis = false +value pro1b: isPrivateThis = false, isProtectedThis = true +method pro2a: isPrivateThis = false, isProtectedThis = true +method pro2b: isPrivateThis = false, isProtectedThis = true +method pro3a: isPrivateThis = false, isProtectedThis = true +method pro3a_=: isPrivateThis = false, isProtectedThis = true +variable pro3a: isPrivateThis = true, isProtectedThis = false +method pro3b: isPrivateThis = false, isProtectedThis = true +method pro3b_=: isPrivateThis = false, isProtectedThis = true +value pro4a: isPrivateThis = false, isProtectedThis = true +lazy value pro4a: isPrivateThis = true, isProtectedThis = false +type Pro5a: isPrivateThis = false, isProtectedThis = true +type Pro5b: isPrivateThis = false, isProtectedThis = true +class Pro6: isPrivateThis = false, isProtectedThis = true +trait Pro7: isPrivateThis = false, isProtectedThis = true +object Pro8: isPrivateThis = false, isProtectedThis = true diff --git a/test/files/run/t6733.scala b/test/files/run/t6733.scala new file mode 100644 index 0000000000..525b276811 --- /dev/null +++ b/test/files/run/t6733.scala @@ -0,0 +1,35 @@ +import scala.reflect.runtime.universe._ + +trait Foo { + private[this] val pri1a = 0 + // private[this] val pri1b: Int + private[this] def pri2a = 1 + // private[this] def pri2b: Int + private[this] var pri3a = 0 + // private[this] var pri3b: Int + private[this] lazy val pri4a = 0 + // private[this] lazy val pri4b: Int + private[this] type Pri5a = Int + // private[this] type Pri5b <: Int + private[this] class Pri6 + private[this] trait Pri7 + private[this] object Pri8 + + protected[this] val pro1a = 0 + protected[this] val pro1b: Int + protected[this] def pro2a = 1 + protected[this] def pro2b: Int + protected[this] var pro3a = 0 + protected[this] var pro3b: Int + protected[this] lazy val pro4a = 0 + // protected[this] lazy val pro4b: Int + protected[this] type Pro5a = Int + protected[this] type Pro5b <: Int + protected[this] class Pro6 + protected[this] trait Pro7 + protected[this] object Pro8 +} + +object Test extends App { + typeOf[Foo].declarations.sorted.foreach(m => println(s"$m: isPrivateThis = ${m.isPrivateThis}, isProtectedThis = ${m.isProtectedThis}")) +}
\ No newline at end of file |